mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-01 07:10:55 +00:00
[repo-setting] Set folder perm
This commit is contained in:
parent
579eb91da6
commit
d1fb67c78f
@ -2786,6 +2786,8 @@ textarea:-moz-placeholder {/* for FF */
|
||||
.view-link-alert p {
|
||||
display: inline-block;
|
||||
}
|
||||
.perm-add-perm,
|
||||
.perm-toggle-select,
|
||||
.share-permission-select,
|
||||
.user-role-select,
|
||||
.user-status-select {
|
||||
@ -3343,3 +3345,26 @@ textarea:-moz-placeholder {/* for FF */
|
||||
background:#fff;
|
||||
z-index:100;
|
||||
}
|
||||
|
||||
/* repo setting */
|
||||
.user-perm-add-perm,
|
||||
.group-perm-add-perm,
|
||||
.perm-toggle-select,
|
||||
.share-permission-select {
|
||||
position:relative;/*for long text in other lang in 'share admin'*/
|
||||
padding:3px 2px;
|
||||
background:#fff;
|
||||
border:1px solid #ddd;
|
||||
border-radius:2px;
|
||||
}
|
||||
.perm-add-select-folder {
|
||||
position:relative;
|
||||
right:18px;
|
||||
cursor:pointer;
|
||||
}
|
||||
.perm-add-jstree-select {
|
||||
margin-top:8px;
|
||||
}
|
||||
#perm-add-jstree-wrap {
|
||||
background:#fcfcfc;
|
||||
}
|
||||
|
@ -713,6 +713,58 @@ FileTree.prototype.renderDirTree = function(container, form, repo_data) {
|
||||
});
|
||||
}
|
||||
|
||||
// list dir by repo
|
||||
FileTree.prototype.renderDirTreeByRepo = function(container, repo_data) {
|
||||
container
|
||||
.bind('select_node.jstree', function(e, data) {
|
||||
var select_path_array = data.inst.get_path(data.rslt.obj);
|
||||
container.next().on("click", { path_array: select_path_array }, selectClickHandler);
|
||||
})
|
||||
.jstree({
|
||||
'json_data': {
|
||||
'data': repo_data,
|
||||
'ajax': {
|
||||
'url': function(data) {
|
||||
var path = this.get_path(data),
|
||||
root = path.shift(),
|
||||
path = root + path.join('/'),
|
||||
site_root = container.data('site_root'),
|
||||
repo_id = container.data('repo_id');
|
||||
|
||||
return site_root + 'ajax/repo/' + repo_id + '/dirents/?path=' + e(path) + '&dir_only=true';
|
||||
},
|
||||
'success': function(data) {
|
||||
var items = [], o, item;
|
||||
for (var i = 0, len = data.length; i < len; i++) {
|
||||
o = data[i];
|
||||
if (o.has_subdir) {
|
||||
item = {
|
||||
'data': o.name,
|
||||
'attr': { 'type': o.type },
|
||||
'state': 'closed'
|
||||
};
|
||||
} else {
|
||||
item = {
|
||||
'data': o.name,
|
||||
'attr': {'type': o.type }
|
||||
};
|
||||
}
|
||||
items.push(item);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
},
|
||||
'plugins': ['themes', 'json_data', 'ui'],
|
||||
'core': {
|
||||
'animation': 100
|
||||
},
|
||||
'ui': {
|
||||
'select_limit': 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function trimFilename(name, n) {
|
||||
var len = name.length;
|
||||
var ext = '';
|
||||
|
@ -63,7 +63,7 @@ from seahub.utils.star import star_file, unstar_file
|
||||
from seahub.utils.file_types import IMAGE, DOCUMENT
|
||||
from seahub.views import validate_owner, is_registered_user, \
|
||||
group_events_data, get_diff, create_default_library, get_owned_repo_list, \
|
||||
list_inner_pub_repos, get_virtual_repos_by_owner
|
||||
list_inner_pub_repos, get_virtual_repos_by_owner, check_folder_permission
|
||||
from seahub.views.ajax import get_share_in_repo_list, get_groups_by_user, \
|
||||
get_group_repos
|
||||
from seahub.views.file import get_file_view_path_and_perm, send_file_download_msg
|
||||
@ -822,8 +822,13 @@ class UploadLinkView(APIView):
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def get(self, request, repo_id, format=None):
|
||||
if check_permission(repo_id, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, "Can not access repo")
|
||||
parent_dir = request.GET.get('p', None)
|
||||
if parent_dir is None:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||
'Missing argument.')
|
||||
|
||||
if check_folder_permission(repo_id, parent_dir, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if check_quota(repo_id) < 0:
|
||||
return api_error(HTTP_520_OPERATION_FAILED, 'Above quota')
|
||||
@ -839,8 +844,13 @@ class UpdateLinkView(APIView):
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def get(self, request, repo_id, format=None):
|
||||
if check_permission(repo_id, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, "Can not access repo")
|
||||
parent_dir = request.GET.get('p', None)
|
||||
if parent_dir is None:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||
'Missing argument.')
|
||||
|
||||
if check_folder_permission(repo_id, parent_dir, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if check_quota(repo_id) < 0:
|
||||
return api_error(HTTP_520_OPERATION_FAILED, 'Above quota')
|
||||
@ -856,8 +866,13 @@ class UploadBlksLinkView(APIView):
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def get(self, request, repo_id, format=None):
|
||||
if check_permission(repo_id, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, "Can not access repo")
|
||||
parent_dir = request.GET.get('p', None)
|
||||
if parent_dir is None:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||
'Missing argument.')
|
||||
|
||||
if check_folder_permission(repo_id, parent_dir, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if check_quota(repo_id) < 0:
|
||||
return api_error(HTTP_520_OPERATION_FAILED, 'Above quota')
|
||||
@ -873,8 +888,13 @@ class UpdateBlksLinkView(APIView):
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def get(self, request, repo_id, format=None):
|
||||
if check_permission(repo_id, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, "Can not access repo")
|
||||
parent_dir = request.GET.get('p', None)
|
||||
if parent_dir is None:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||
'Missing argument.')
|
||||
|
||||
if check_folder_permission(repo_id, parent_dir, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if check_quota(repo_id) < 0:
|
||||
return api_error(HTTP_520_OPERATION_FAILED, 'Above quota')
|
||||
@ -1127,9 +1147,17 @@ class OpCopyView(APIView):
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'You do not have permission to delete file.')
|
||||
|
||||
resp = check_repo_access_permission(request, repo)
|
||||
if resp:
|
||||
return resp
|
||||
parent_dir = request.GET.get('p', None)
|
||||
dst_repo = request.POST.get('dst_repo', None)
|
||||
dst_dir = request.POST.get('dst_dir', None)
|
||||
file_names = request.POST.get("file_names", None)
|
||||
|
||||
if not parent_dir or not file_names or not dst_repo or not dst_dir:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||
'Missing argument.')
|
||||
|
||||
if check_folder_permission(repo_id, parent_dir, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
parent_dir = request.GET.get('p', None)
|
||||
dst_repo = request.POST.get('dst_repo', None)
|
||||
@ -1254,16 +1282,16 @@ class FileView(APIView):
|
||||
if not repo:
|
||||
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
|
||||
|
||||
resp = check_repo_access_permission(request, repo)
|
||||
if resp:
|
||||
return resp
|
||||
|
||||
path = request.GET.get('p', '')
|
||||
username = request.user.username
|
||||
parent_dir = os.path.dirname(path)
|
||||
if check_folder_permission(repo_id, parent_dir, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if not path or path[0] != '/':
|
||||
return api_error(status.HTTP_400_BAD_REQUEST,
|
||||
'Path is missing or invalid.')
|
||||
|
||||
username = request.user.username
|
||||
operation = request.POST.get('operation', '')
|
||||
if operation.lower() == 'rename':
|
||||
if not is_repo_writable(repo.id, username):
|
||||
@ -1404,14 +1432,14 @@ class FileView(APIView):
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'You do not have permission to delete file.')
|
||||
|
||||
resp = check_repo_access_permission(request, repo)
|
||||
if resp:
|
||||
return resp
|
||||
|
||||
path = request.GET.get('p', None)
|
||||
if not path:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.')
|
||||
|
||||
parent_dir = os.path.dirname(path)
|
||||
if check_folder_permission(repo_id, parent_dir, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
parent_dir_utf8 = os.path.dirname(path).encode('utf-8')
|
||||
file_name_utf8 = os.path.basename(path).encode('utf-8')
|
||||
|
||||
@ -1481,12 +1509,17 @@ class FileRevert(APIView):
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def put(self, request, repo_id, format=None):
|
||||
path = unquote(request.DATA.get('p', '').encode('utf-8'))
|
||||
path = request.DATA.get('p', '')
|
||||
if not path:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.')
|
||||
|
||||
parent_dir = os.path.dirname(path)
|
||||
username = request.uset.username
|
||||
if check_folder_permission(repo_id, parent_dir, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
path = unquote(path.encode('utf-8'))
|
||||
commit_id = unquote(request.DATA.get('commit_id', '').encode('utf-8'))
|
||||
if not path:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.')
|
||||
try:
|
||||
ret = seafserv_threaded_rpc.revert_file (repo_id, commit_id,
|
||||
path, request.user.username)
|
||||
@ -1636,11 +1669,8 @@ class DirView(APIView):
|
||||
if not repo:
|
||||
return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.')
|
||||
|
||||
resp = check_repo_access_permission(request, repo)
|
||||
if resp:
|
||||
return resp
|
||||
|
||||
path = request.GET.get('p', '')
|
||||
|
||||
if not path or path[0] != '/':
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, "Path is missing.")
|
||||
if path == '/': # Can not make or rename root dir.
|
||||
@ -1650,13 +1680,16 @@ class DirView(APIView):
|
||||
|
||||
username = request.user.username
|
||||
operation = request.POST.get('operation', '')
|
||||
|
||||
|
||||
if operation.lower() == 'mkdir':
|
||||
if not is_repo_writable(repo.id, username):
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'You do not have permission to create folder.')
|
||||
|
||||
parent_dir = os.path.dirname(path)
|
||||
if check_folder_permission(repo_id, parent_dir, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
parent_dir_utf8 = parent_dir.encode('utf-8')
|
||||
new_dir_name = os.path.basename(path)
|
||||
new_dir_name_utf8 = check_filename_with_rename_utf8(repo_id,
|
||||
@ -1679,11 +1712,13 @@ class DirView(APIView):
|
||||
quote(new_dir_name_utf8)
|
||||
return resp
|
||||
elif operation.lower() == 'rename':
|
||||
if check_folder_permission(repo.id, path, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if not is_repo_writable(repo.id, username):
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'You do not have permission to rename a folder.')
|
||||
|
||||
parent_dir = os.path.dirname(path)
|
||||
old_dir_name = os.path.basename(path)
|
||||
|
||||
newname = request.POST.get('newname', '')
|
||||
@ -1722,14 +1757,13 @@ class DirView(APIView):
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'You do not have permission to delete folder.')
|
||||
|
||||
resp = check_repo_access_permission(request, repo)
|
||||
if resp:
|
||||
return resp
|
||||
|
||||
path = request.GET.get('p', None)
|
||||
if not path:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.')
|
||||
|
||||
if check_folder_permission(repo_id, path, username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.')
|
||||
|
||||
if path == '/': # Can not delete root path.
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, 'Path is invalid.')
|
||||
|
||||
|
@ -35,7 +35,8 @@ from seahub.base.decorators import user_mods_check
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.contacts.signals import mail_sended
|
||||
from seahub.signals import share_file_to_user_successful
|
||||
from seahub.views import is_registered_user, check_repo_access_permission
|
||||
from seahub.views import is_registered_user, check_repo_access_permission, \
|
||||
check_folder_permission
|
||||
from seahub.utils import render_permission_error, string2list, render_error, \
|
||||
gen_token, gen_shared_link, gen_shared_upload_link, gen_dir_share_link, \
|
||||
gen_file_share_link, IS_EMAIL_CONFIGURED, check_filename_with_rename, \
|
||||
@ -1104,7 +1105,11 @@ def get_shared_upload_link(request):
|
||||
path += '/'
|
||||
|
||||
repo = seaserv.get_repo(repo_id)
|
||||
user_perm = check_repo_access_permission(repo.id, request.user)
|
||||
if not repo:
|
||||
messages.error(request, _(u'Library does not exist'))
|
||||
return HttpResponse(status=400, content_type=content_type)
|
||||
|
||||
user_perm = check_folder_permission(repo.id, path, request.user.username)
|
||||
|
||||
if user_perm == 'r':
|
||||
messages.error(request, _(u'Permission denied'))
|
||||
|
@ -27,7 +27,7 @@
|
||||
<a href="{{ SITE_ROOT }}seafile_access_check/?repo_id={{repo.props.id}}" target="_blank">{% trans "Download" %}</a>
|
||||
{% endif %}
|
||||
{% if show_repo_settings %}
|
||||
<a id="repo-setting-btn" href="{% url 'repo_settings' repo.id %}" class="normal"><img class="link-icon vam" src="{{ MEDIA_URL }}img/setting.png" alt="" /><span class="vam">{% trans "Settings" %}</span></a>
|
||||
<a id="repo-setting-btn" href="{% url 'repo_basic_info' repo.id %}" class="normal"><img class="link-icon vam" src="{{ MEDIA_URL }}img/setting.png" alt="" /><span class="vam">{% trans "Settings" %}</span></a>
|
||||
{% endif %}
|
||||
{% if user_perm == 'rw' %}
|
||||
<a id="recycle-btn" href="{% url 'repo_recycle_view' repo.id %}" class="normal"><img class="link-icon vam" src="{{ MEDIA_URL }}img/lib_trash.png" alt="" /><span class="vam">{% trans "Trash"%}</span></a>
|
||||
@ -343,8 +343,12 @@ $(function() {
|
||||
// get url(token) for every file
|
||||
if (!file.error) {
|
||||
$.ajax({
|
||||
url: '{% url 'get_file_op_url' repo.id %}?op_type=upload',
|
||||
url: '{% url 'get_file_op_url' repo.id %}',
|
||||
cache: false,
|
||||
data: {
|
||||
'op_type': 'upload',
|
||||
'path': cur_path
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(ret) {
|
||||
{% if enable_upload_folder %}
|
||||
@ -1221,8 +1225,12 @@ $('#upload-file').click(function () {
|
||||
|
||||
$.modal.close();
|
||||
$.ajax({
|
||||
url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('upload-blks'),
|
||||
url: '{% url 'get_file_op_url' repo.id %}',
|
||||
cache: false,
|
||||
data: {
|
||||
'op_type': 'upload-blks',
|
||||
'path': cur_path
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
encAndSubmitFile(file, fd, data['url']);
|
||||
@ -1745,8 +1753,12 @@ $('.file-update', context).click(function() {
|
||||
$.modal.close();
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('update-blks'),
|
||||
url: '{% url 'get_file_op_url' repo.id %}',
|
||||
cache: false,
|
||||
data: {
|
||||
'op_type': 'update-blks',
|
||||
'path': cur_path
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var sb_url = data['url'] + '?head=' + $('#repo-latest-commit .commit-msg').data('cmtid');
|
||||
@ -1781,8 +1793,12 @@ $('.file-update', context).click(function() {
|
||||
hd.html(hd.html().replace('%(file_name)s', '<span class="op-target">' + file_name + '</span>'));
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('update'),
|
||||
url: '{% url 'get_file_op_url' repo.id %}',
|
||||
cache: false,
|
||||
data: {
|
||||
'op_type': 'update',
|
||||
'path': cur_path
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
// Initialize the jQuery File Upload widget:
|
||||
|
125
seahub/templates/repo_basic_info.html
Normal file
125
seahub/templates/repo_basic_info.html
Normal file
@ -0,0 +1,125 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab tab-cur"><a href="{% url 'repo_basic_info' repo.id %}">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_transfer_owner' repo.id %}">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab"><a href="{% url 'repo_change_password' repo.id %}">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab"><a href="{% url 'repo_shared_link' repo.id %}">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Management" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "SubFolder Permission" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
<div id="basic-info" class="setting-item">
|
||||
<h3>{% trans "Basic Info" %}</h3>
|
||||
<form id="repo-basic-info-form" action="" method="post" class="form">{% csrf_token %}
|
||||
<label>{% trans "Name" %}</label><br />
|
||||
<input type="text" name="repo_name" value="{{ repo.name }}" class="input" /><br />
|
||||
<label>{% trans "Description" %}</label></br />
|
||||
<textarea name="repo_desc" class="textarea">{{ repo.desc }}</textarea><br />
|
||||
|
||||
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
|
||||
<label>{% trans "History" %}</label><br />
|
||||
<input type="radio" name="history" value="full_history" {% if full_history_checked %}checked="checked"{% endif %} class="vam" {% if not full_history_enabled %}disabled="disabled"{% endif %} /> <span class="vam">{% trans "Keep full history" %}</span><br />
|
||||
<input type="radio" name="history" value="no_history" {% if no_history_checked %}checked="checked"{% endif %} class="vam" {% if not full_history_enabled %}disabled="disabled"{% endif %} /> <span class="vam">{% trans "Don't keep history" %}</span><br />
|
||||
<input type="radio" name="history" value="partial_history" {% if partial_history_checked %}checked="checked"{% endif %} class="vam" {% if not full_history_enabled %}disabled="disabled"{% endif %} /> <span calss="vam">{% trans "Only keep a period of history:" %}
|
||||
<input type="text" name="days" size="4" {% if not days_enabled %} disabled="disabled" class="input-disabled"{% endif %} value="{{history_limit}}" /> {% trans "days" %}</span><br />
|
||||
{% endif %}
|
||||
|
||||
<p class="error hide"></p>
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$('#repo-basic-info-form input[name="history"]').change(function() {
|
||||
var value = $(this).attr('value'),
|
||||
days_input = $('#repo-basic-info-form input[name="days"]');
|
||||
if (value == 'full_history' || value == 'no_history') {
|
||||
days_input.attr('disabled', true).addClass('input-disabled');
|
||||
} else {
|
||||
days_input.attr('disabled', false).removeClass('input-disabled');
|
||||
}
|
||||
});
|
||||
|
||||
$('#repo-basic-info-form').submit(function() {
|
||||
var form = $(this),
|
||||
form_id = form.attr('id');
|
||||
var repo_name = $('[name="repo_name"]', form).val(),
|
||||
repo_desc = $('[name="repo_desc"]', form).val();
|
||||
|
||||
if (!$.trim(repo_name)) {
|
||||
apply_form_error(form_id, "{% trans "Name is required." %}");
|
||||
return false;
|
||||
}
|
||||
if (!$.trim(repo_desc)) {
|
||||
apply_form_error(form_id, "{% trans "Description is required." %}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var days;
|
||||
var value = $(this).find('input[name="history"]:checked').val();
|
||||
|
||||
if (value == 'partial_history') {
|
||||
days = $(this).find('input[name="days"]').val();
|
||||
} else if (value == 'full_history') {
|
||||
days = -1;
|
||||
} else {
|
||||
days = 0;
|
||||
}
|
||||
|
||||
var submit_btn = $(this).children('input[type="submit"]');
|
||||
disable(submit_btn);
|
||||
$.ajax({
|
||||
url: '{% url 'ajax_repo_change_basic_info' repo.id %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'repo_name': repo_name,
|
||||
'repo_desc': repo_desc,
|
||||
'days': days
|
||||
},
|
||||
success: function(data) {
|
||||
if (data['success']) {
|
||||
location.reload(true);
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText) {
|
||||
apply_form_error(form_id, $.parseJSON(jqXHR.responseText).error);
|
||||
} else {
|
||||
apply_form_error(form_id, "{% trans "Failed. Please check the network." %}");
|
||||
}
|
||||
enable(submit_btn);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
116
seahub/templates/repo_change_password.html
Normal file
116
seahub/templates/repo_change_password.html
Normal file
@ -0,0 +1,116 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab"><a href="{% url 'repo_basic_info' repo.id %}">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_transfer_owner' repo.id %}">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab tab-cur"><a href="{% url 'repo_change_password' repo.id %}">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab"><a href="{% url 'repo_shared_link' repo.id %}">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Management" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "SubFolder Permission" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
<div id="change-password" class="setting-item">
|
||||
<h3>{% trans "Change Password" %}</h3>
|
||||
<form id="repo-change-passwd-form" action="" method="post" class="form">{% csrf_token %}
|
||||
<p>{% trans "Change the password of this library:" %}</p>
|
||||
<label>{% trans "Old Password" %}</label><br />
|
||||
<input type="password" name="old_passwd" class="input" /><br />
|
||||
<label>{% blocktrans %}New Password(at least {{repo_password_min_length}} characters){% endblocktrans %}</label><br />
|
||||
<input type="password" name="new_passwd" class="input" /><br />
|
||||
<label>{% trans "New Password Again" %}</label><br />
|
||||
<input type="password" name="new_passwd_again" class="input" /><br />
|
||||
<p class="error hide"></p>
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
$('#repo-change-passwd-form').submit(function() {
|
||||
var form = $(this),
|
||||
form_id = form.attr('id'),
|
||||
old_passwd, new_passwd, new_passwd_again;
|
||||
|
||||
old_passwd = $('input[name="old_passwd"]', form).val();
|
||||
new_passwd = $('input[name="new_passwd"]', form).val();
|
||||
new_passwd_again = $('input[name="new_passwd_again"]', form).val();
|
||||
|
||||
if (!$.trim(old_passwd)) {
|
||||
apply_form_error(form_id, "{% trans "Please enter the old password" %}");
|
||||
return false;
|
||||
}
|
||||
if (!$.trim(new_passwd)) {
|
||||
apply_form_error(form_id, "{% trans "Please enter the new password" %}");
|
||||
return false;
|
||||
}
|
||||
if ($.trim(new_passwd).length < {{repo_password_min_length}}) {
|
||||
apply_form_error(form_id, "{% trans "New password is too short" %}");
|
||||
return false;
|
||||
}
|
||||
if (!$.trim(new_passwd_again)) {
|
||||
apply_form_error(form_id, "{% trans "Please enter the new password again" %}");
|
||||
return false;
|
||||
}
|
||||
if ($.trim(new_passwd) != $.trim(new_passwd_again)) {
|
||||
apply_form_error(form_id, "{% trans "New passwords don't match" %}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var submit_btn = $(this).children('input[type="submit"]');
|
||||
disable(submit_btn);
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'ajax_repo_change_passwd' repo.id %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'old_passwd': old_passwd,
|
||||
'new_passwd': new_passwd,
|
||||
'new_passwd_again': new_passwd_again
|
||||
},
|
||||
success: function(data) {
|
||||
if (data['success']) {
|
||||
location.reload(true);
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText) {
|
||||
apply_form_error(form_id, $.parseJSON(jqXHR.responseText).error);
|
||||
} else {
|
||||
apply_form_error(form_id, "{% trans "Failed. Please check the network." %}");
|
||||
}
|
||||
enable(submit_btn);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
393
seahub/templates/repo_folder_perm.html
Normal file
393
seahub/templates/repo_folder_perm.html
Normal file
@ -0,0 +1,393 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab"><a href="{% url 'repo_basic_info' repo.id %}">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_transfer_owner' repo.id %}">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab"><a href="{% url 'repo_change_password' repo.id %}">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab"><a href="{% url 'repo_shared_link' repo.id %}">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Management" %}</a></li>
|
||||
<li class="tab tab-cur"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "SubFolder Permission" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
<h3>{% trans "Folder Permission" %}</h3>
|
||||
<p>{% trans "View and manage all the folder permissions in this library." %}</p>
|
||||
<div id="tabs" class="tab-tabs">
|
||||
<div class="hd ovhd">
|
||||
<ul class="tab-tabs-nav fleft">
|
||||
<li class="tab"><a href="#user-tab" class="a" id="user-tab">{% trans "User Permission" %}</a></li>
|
||||
<li class="tab"><a href="#group-tab" class="a" id="group-tab">{% trans "Group permission" %}</a></li>
|
||||
</ul>
|
||||
<div class="fright">
|
||||
<button id="folder-perm-add-btn"><img src="{{ MEDIA_URL }}img/add.png" alt="" class="add vam" /><span class="vam">{% trans "Add Permission" %}</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="user-tab">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="30%">{% trans "User" %}</th>
|
||||
<th width="30%">{% trans "Folder" %}</th>
|
||||
<th width="30%">{% trans "Permission" %}</th>
|
||||
<th width="10%"></th>
|
||||
</tr>
|
||||
<tr class="user-perm-add-tr hide">
|
||||
<td><input id="perm-add-user" placeholder=" {% trans "Email"%}"></input></td>
|
||||
<td>
|
||||
<input class="user-perm-add-folder-name" placeholder=" {% trans "Select a folder"%}"></input><img src="{{ MEDIA_URL }}img/add.png" alt="" title="Select Folder" class="perm-add-select-folder add vam" />
|
||||
<input class="user-perm-add-folder-path" type="hidden"></input>
|
||||
</td>
|
||||
<td>
|
||||
<select name="permission" class="user-perm-add-perm">
|
||||
<option value="rw" selected="selected">{% trans "Read-Write"%}</option>
|
||||
<option value="r">{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button class="perm-add-submit">{% trans "Submit" %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% if user_folder_perms %}
|
||||
{% for perm in user_folder_perms %}
|
||||
<tr class="perm-item" data-user="{{ perm.user }}" data-path="{{ perm.path }}">
|
||||
<td><a href="{% url 'user_profile' perm.user %}">{{ perm.user }}</a></td>
|
||||
<td><span><a href="{{ perm.folder_link }}">{{ perm.folder_name }}</a></span></td>
|
||||
<td>
|
||||
<div class="perm-change">
|
||||
{% if perm.permission == 'rw' %}
|
||||
<span class="perm-cur-value">{% trans "Read-Write" %}</span>
|
||||
{% else %}
|
||||
<span class="perm-cur-value">{% trans "Read-Only" %}</span>
|
||||
{% endif %}
|
||||
<img src="{{MEDIA_URL}}img/edit_12.png" alt="{% trans "Edit"%}" title="{% trans "Edit"%}" class="perm-edit-icon cspt vh" />
|
||||
</div>
|
||||
<select class="perm-toggle-select hide">
|
||||
<option value="rw" {%if perm.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Write" %}</option>
|
||||
<option value="r" {%if not perm.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<img src="{{MEDIA_URL}}img/rm.png" class="perm-delete-btn op-icon vh" title="{% trans "Delete" %}" />
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="group-tab" class="hide">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="30%">{% trans "Group" %}</th>
|
||||
<th width="30%">{% trans "Folder" %}</th>
|
||||
<th width="30%">{% trans "Permission" %}</th>
|
||||
<th width="10%"></th>
|
||||
</tr>
|
||||
<tr class="group-perm-add-tr hide">
|
||||
<td>
|
||||
<input id="perm-add-grp-name" placeholder=" {% trans "Group"%}"></input>
|
||||
<input id="perm-add-grp-id" type="hidden"></input>
|
||||
</td>
|
||||
<td>
|
||||
<input class="group-perm-add-folder-name" placeholder=" {% trans "Select a folder"%}"></input><img src="{{ MEDIA_URL }}img/add.png" alt="" title="Select Folder" class="perm-add-select-folder add vam" />
|
||||
<input class="group-perm-add-folder-path" type="hidden"></input>
|
||||
</td>
|
||||
<td>
|
||||
<select name="permission" class="group-perm-add-perm">
|
||||
<option value="rw" selected="selected">{% trans "Read-Write"%}</option>
|
||||
<option value="r">{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button class="perm-add-submit">{% trans "Submit" %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% if group_folder_perms %}
|
||||
{% for perm in group_folder_perms %}
|
||||
<tr class="perm-item" data-group_id="{{ perm.group_id }}" data-path="{{ perm.path }}">
|
||||
<td><a href="{% url 'group_info' perm.group_id %}">{{ perm.group_name }}</a></td>
|
||||
<td>
|
||||
<span><a href="{{ perm.folder_link }}">{{ perm.folder_name }}</a></span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="perm-change">
|
||||
{% if perm.permission == 'rw' %}
|
||||
<span class="perm-cur-value">{% trans "Read-Write" %}</span>
|
||||
{% else %}
|
||||
<span class="perm-cur-value">{% trans "Read-Only" %}</span>
|
||||
{% endif %}
|
||||
<img src="{{MEDIA_URL}}img/edit_12.png" alt="{% trans "Edit"%}" title="{% trans "Edit"%}" class="perm-edit-icon cspt vh" />
|
||||
</div>
|
||||
<select class="perm-toggle-select hide">
|
||||
<option value="rw" {%if perm.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Write" %}</option>
|
||||
<option value="r" {%if not perm.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<img src="{{MEDIA_URL}}img/rm.png" class="perm-delete-btn op-icon vh" title="{% trans "Delete" %}" />
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="perm-add-jstree-wrap" class="hide">
|
||||
<h3>{% trans "Please selecte a directory" %}</h3>
|
||||
<img src="{{MEDIA_URL}}img/loading-icon.gif" alt="" class="loading-tip" />
|
||||
<div id="perm-add-jstree" data-repo_id="{{repo.id}}"></div>
|
||||
<button class="perm-add-jstree-select">{% trans "Select" %}</button>
|
||||
<button class="simplemodal-close">{% trans "Cancel"%}</button><br />
|
||||
<span class="error hide"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
{% include "repo_setting_extra_js.html" %}
|
||||
|
||||
var user_perm_add_tr = $('.user-perm-add-tr'),
|
||||
group_perm_add_tr = $('.group-perm-add-tr');
|
||||
|
||||
$('#user-tab').click(function() {
|
||||
group_perm_add_tr.addClass('hide');
|
||||
});
|
||||
$('#group-tab').click(function() {
|
||||
user_perm_add_tr.addClass('hide');
|
||||
});
|
||||
|
||||
var user_list = [], contact,
|
||||
group_list = [], group_name, group_id,
|
||||
user_input = $('#perm-add-user'),
|
||||
group_input = $('#perm-add-grp-name');
|
||||
|
||||
{% for contact in contacts %}
|
||||
contact = '{{ contact }}';
|
||||
user_list.push({value:contact, label:contact});
|
||||
{% endfor %}
|
||||
|
||||
{% for group in request.user.joined_groups %}
|
||||
group_name = '{{ group.group_name }}';
|
||||
group_id = '{{ group.id }}';
|
||||
group_list.push({value:group_id, label:group_name});
|
||||
{% endfor %}
|
||||
|
||||
user_input.bind('autocompleteopen', function(e, ui) {
|
||||
var widget = user_input.autocomplete('widget');
|
||||
widget.css({'max-width':user_input.width() - 2 * parseInt(widget.css('padding')), 'max-height':$(window).height() + $(window).scrollTop() - user_input.offset().top - user_input.outerHeight()});
|
||||
})
|
||||
.autocomplete({
|
||||
source: user_list
|
||||
});
|
||||
|
||||
group_input.bind('autocompleteopen', function(e, ui) {
|
||||
var widget = group_input.autocomplete('widget');
|
||||
widget.css({'max-width':group_input.width() - 2 * parseInt(widget.css('padding')), 'max-height':$(window).height() + $(window).scrollTop() - group_input.offset().top - group_input.outerHeight()});
|
||||
})
|
||||
.autocomplete({
|
||||
source: group_list,
|
||||
select: function(event, ui) {
|
||||
// prevent autocomplete from updating the textbox
|
||||
event.preventDefault();
|
||||
// manually update the textbox and hidden field
|
||||
group_input.val(ui.item.label);
|
||||
$('#perm-add-grp-id').val(ui.item.value);
|
||||
}
|
||||
});
|
||||
|
||||
$('#folder-perm-add-btn').click(function() {
|
||||
if (is_user_tab == true) {
|
||||
user_perm_add_tr.removeClass('hide');
|
||||
$('.user-perm-add-folder-name').val('');
|
||||
user_input.focus().val('');
|
||||
} else {
|
||||
group_perm_add_tr.removeClass('hide');
|
||||
$('.group-perm-add-folder-name').val('');
|
||||
group_input.focus().val('');
|
||||
}
|
||||
});
|
||||
|
||||
$('.perm-toggle-select').on('change', function() {
|
||||
var select = $(this),
|
||||
perm_item = select.parents('.perm-item'),
|
||||
path = perm_item.attr('data-path'),
|
||||
perm = select.val();
|
||||
|
||||
if (is_user_tab == true) {
|
||||
var user = perm_item.attr('data-user'),
|
||||
data = { 'user': user, 'path': path, 'perm': perm },
|
||||
url = '{% url 'toggle_user_folder_permission' repo.id %}';
|
||||
} else {
|
||||
var group_id = perm_item.attr('data-group_id'),
|
||||
data = { 'group_id': group_id, 'path': path, 'perm': perm },
|
||||
url = '{% url 'toggle_group_folder_permission' repo.id %}';
|
||||
}
|
||||
|
||||
perm_toggle(select, data, url)
|
||||
});
|
||||
$('.perm-delete-btn').on('click', function() {
|
||||
var perm_item = $(this).parents('.perm-item'),
|
||||
path = perm_item.attr('data-path');
|
||||
|
||||
if (is_user_tab == true) {
|
||||
var user = perm_item.attr('data-user'),
|
||||
data = { 'user': user, 'path': path },
|
||||
url = '{% url 'remove_user_folder_permission' repo.id %}';
|
||||
} else {
|
||||
var group_id = perm_item.attr('data-group_id'),
|
||||
data = { 'group_id': group_id, 'path': path },
|
||||
url = '{% url 'remove_group_folder_permission' repo.id %}';
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
data: data,
|
||||
success: function() {
|
||||
perm_item.remove();
|
||||
feedback("{% trans "Delete succeeded" %}", 'success');
|
||||
},
|
||||
error: ajaxErrorHandler
|
||||
});
|
||||
});
|
||||
$('.perm-add-submit').click(function() {
|
||||
if (is_user_tab == true) {
|
||||
var path = $('.user-perm-add-folder-path').val();
|
||||
if (!$.trim(path)) {
|
||||
path = $('.user-perm-add-folder-name').val();
|
||||
}
|
||||
|
||||
var user = user_input.val(),
|
||||
perm = $('.user-perm-add-perm').val(),
|
||||
data = { 'user': user, 'path': path, 'perm': perm },
|
||||
url = '{% url 'add_user_folder_permission' repo.id %}';
|
||||
} else {
|
||||
var path = $('.group-perm-add-folder-path').val();
|
||||
if (!$.trim(path)) {
|
||||
path = $('.group-perm-add-folder-name').val();
|
||||
}
|
||||
|
||||
var group_id = $('#perm-add-grp-id').val(),
|
||||
perm = $('.group-perm-add-perm').val(),
|
||||
data = { 'group_id': group_id, 'path': path, 'perm': perm },
|
||||
url = '{% url 'add_group_folder_permission' repo.id %}';
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: data,
|
||||
success: function() {
|
||||
location.reload();
|
||||
},
|
||||
error: ajaxErrorHandler
|
||||
});
|
||||
});
|
||||
|
||||
$('.perm-add-select-folder').click(function() {
|
||||
$('#perm-add-jstree-wrap').modal({appendTo:'#main', autoResize:true, focus:false});
|
||||
$('#simplemodal-container').css({'width':'auto', 'height':'auto'});
|
||||
render_jstree($('#perm-add-jstree'))
|
||||
});
|
||||
|
||||
function selectClickHandler(event) {
|
||||
var path, folder_name, folder_path,
|
||||
path_array = event.data.path_array;
|
||||
|
||||
if (is_user_tab == true) {
|
||||
folder_name = $('.user-perm-add-folder-name');
|
||||
folder_path = $('.user-perm-add-folder-path');
|
||||
} else {
|
||||
folder_name = $('.group-perm-add-folder-name');
|
||||
folder_path = $('.group-perm-add-folder-path');
|
||||
}
|
||||
if (path_array.length == 1) {
|
||||
path = path_array.shift();
|
||||
folder_name.val('Root Directory');
|
||||
} else {
|
||||
var root = path_array.shift(),
|
||||
path = root + path_array.join('/'),
|
||||
name = path.split('/');
|
||||
|
||||
folder_name.val(name.pop());
|
||||
}
|
||||
|
||||
folder_path.val(path);
|
||||
$.modal.close();
|
||||
};
|
||||
|
||||
function render_jstree(container) {
|
||||
var base_path = '/', loading_tip = $('.loading-tip'),
|
||||
file_tree = new FileTree();
|
||||
|
||||
container.data('site_root', '{{SITE_ROOT}}');
|
||||
container.data('repo_id', '{{repo.id}}');
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'get_dirents' repo.id %}?path=' + e(base_path) + '&dir_only=true&all_dir=true',
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var json_data = [], children = [],
|
||||
repo_data = {'data': base_path, 'attr': {'root_node': true}, 'state': 'open'};
|
||||
|
||||
for (var i = 0, len = data[0].length; i < len; i++) {
|
||||
children.push({ 'data': data[0][i], 'state': 'closed' });
|
||||
}
|
||||
if (children.length > 0) {
|
||||
$.extend(repo_data, {'children': children});
|
||||
}
|
||||
json_data.push(repo_data);
|
||||
|
||||
loading_tip.hide();
|
||||
file_tree.renderDirTreeByRepo(container, json_data, selectClickHandler);
|
||||
container.removeClass('hide');
|
||||
},
|
||||
error: function() {
|
||||
var cur_repo = [{
|
||||
'data': base_path,
|
||||
'attr': {'root_node': true},
|
||||
'state': 'open'
|
||||
}];
|
||||
|
||||
loading_tip.hide();
|
||||
renderDirTree(container, json_data);
|
||||
container.removeClass('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
$('.perm-add-jstree-select').click(function() {
|
||||
if($("#perm-add-jstree:has('.jstree-clicked')").length == 0) {
|
||||
$('#perm-add-jstree-wrap').find('.error')
|
||||
.removeClass('hide')
|
||||
.html('Please select a folder');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
58
seahub/templates/repo_setting_extra_js.html
Normal file
58
seahub/templates/repo_setting_extra_js.html
Normal file
@ -0,0 +1,58 @@
|
||||
{% load i18n %}
|
||||
|
||||
var cur_tab = $('.ui-tabs-selected .a');
|
||||
if (cur_tab.attr('id') == 'user-tab') {
|
||||
var is_user_tab = new Boolean(true);
|
||||
} else {
|
||||
var is_user_tab = new Boolean(false);
|
||||
}
|
||||
$('#user-tab').click(function() {
|
||||
is_user_tab = new Boolean(true);
|
||||
});
|
||||
$('#group-tab').click(function() {
|
||||
is_user_tab = new Boolean(false);
|
||||
});
|
||||
|
||||
$('.perm-item').on({
|
||||
mouseenter: function() {
|
||||
var perm_item = $(this);
|
||||
perm_item.find('.perm-edit-icon').removeClass('vh');
|
||||
perm_item.find('.perm-delete-btn').removeClass('vh');
|
||||
},
|
||||
mouseleave: function() {
|
||||
var perm_item = $(this);
|
||||
perm_item.find('.perm-edit-icon').addClass('vh');
|
||||
perm_item.find('.perm-delete-btn').addClass('vh');
|
||||
}
|
||||
});
|
||||
$('.perm-edit-icon').on('click', function() {
|
||||
$(this).parent().addClass('hide')
|
||||
.next().removeClass('hide');
|
||||
});
|
||||
|
||||
function perm_toggle(select, data, url) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: data,
|
||||
success: function(data) {
|
||||
select.addClass('hide')
|
||||
.prev().removeClass('hide')
|
||||
.children('span')
|
||||
.html(select.children('option[value="' + select.val() + '"]').text());
|
||||
feedback("{% trans "Success" %}", 'success');
|
||||
},
|
||||
error: ajaxErrorHandler
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click', function(e) {
|
||||
var target = e.target || event.srcElement;
|
||||
if (!$('.perm-edit-icon, .perm-toggle-select').is(target)) {
|
||||
$('.perm-change').removeClass('hide');
|
||||
$('.perm-toggle-select').addClass('hide');
|
||||
}
|
||||
});
|
@ -1,359 +0,0 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab tab-cur"><a href="#basic-info">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab"><a href="#transfer-ownership">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab"><a href="#change-password">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab"><a href="#shared-links">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
|
||||
<div id="basic-info" class="setting-item">
|
||||
<h3>{% trans "Basic Info" %}</h3>
|
||||
<form id="repo-basic-info-form" action="" method="post" class="form">{% csrf_token %}
|
||||
<label>{% trans "Name" %}</label><br />
|
||||
<input type="text" name="repo_name" value="{{ repo.name }}" class="input" /><br />
|
||||
<label>{% trans "Description" %}</label></br />
|
||||
<textarea name="repo_desc" class="textarea">{{ repo.desc }}</textarea><br />
|
||||
|
||||
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
|
||||
<label>{% trans "History" %}</label><br />
|
||||
<input type="radio" name="history" value="full_history" {% if full_history_checked %}checked="checked"{% endif %} class="vam" {% if not full_history_enabled %}disabled="disabled"{% endif %} /> <span class="vam">{% trans "Keep full history" %}</span><br />
|
||||
<input type="radio" name="history" value="no_history" {% if no_history_checked %}checked="checked"{% endif %} class="vam" {% if not full_history_enabled %}disabled="disabled"{% endif %} /> <span class="vam">{% trans "Don't keep history" %}</span><br />
|
||||
<input type="radio" name="history" value="partial_history" {% if partial_history_checked %}checked="checked"{% endif %} class="vam" {% if not full_history_enabled %}disabled="disabled"{% endif %} /> <span calss="vam">{% trans "Only keep a period of history:" %}
|
||||
<input type="text" name="days" size="4" {% if not days_enabled %} disabled="disabled" class="input-disabled"{% endif %} value="{{history_limit}}" /> {% trans "days" %}</span><br />
|
||||
{% endif %}
|
||||
|
||||
<p class="error hide"></p>
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="transfer-ownership" class="setting-item hide">
|
||||
<h3>{% trans "Transfer Ownership" %}</h3>
|
||||
<form id="repo-owner-form" action="" method="post" class="form">{% csrf_token %}
|
||||
<p>{% trans "Transfer this library to another user:" %}</p>
|
||||
<input type="text" name="repo_owner" value="" placeholder="{% trans "Email" %}" class="input" /><br />
|
||||
<p class="error hide"></p>
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<div id="change-password" class="setting-item hide">
|
||||
<h3>{% trans "Change Password" %}</h3>
|
||||
<form id="repo-change-passwd-form" action="" method="post" class="form">{% csrf_token %}
|
||||
<p>{% trans "Change the password of this library:" %}</p>
|
||||
<label>{% trans "Old Password" %}</label><br />
|
||||
<input type="password" name="old_passwd" class="input" /><br />
|
||||
<label>{% blocktrans %}New Password(at least {{repo_password_min_length}} characters){% endblocktrans %}</label><br />
|
||||
<input type="password" name="new_passwd" class="input" /><br />
|
||||
<label>{% trans "New Password Again" %}</label><br />
|
||||
<input type="password" name="new_passwd_again" class="input" /><br />
|
||||
<p class="error hide"></p>
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if not repo.encrypted %}
|
||||
<div id="shared-links" class="setting-item hide">
|
||||
<h3>{% trans "Shared Links" %}</h3>
|
||||
<p>{% trans "View and manage all the shared links in this library." %}</p>
|
||||
<div id="tabs" class="tab-tabs">
|
||||
<ul class="tab-tabs-nav hd ovhd">
|
||||
<li class="tab"><a href="#upload-links" class="a">{% trans "Upload Links" %}</a></li>
|
||||
<li class="tab"><a href="#download-links" class="a">{% trans "Download Links" %}</a></li>
|
||||
</ul>
|
||||
<div id="upload-links">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="5%"><!--icon--></th>
|
||||
<th width="40%">{% trans "Name"%}</th>
|
||||
<th width="15%">{% trans "Created By"%}</th>
|
||||
<th width="15%">{% trans "Size"%}</th>
|
||||
<th width="12%">{% trans "Visits"%}</th>
|
||||
<th width="13%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% if uploadlinks %}
|
||||
{% for link in uploadlinks %}
|
||||
<tr>
|
||||
<td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td>
|
||||
<td><a href="{% url 'repo' repo.id %}?p={{ link.path|urlencode }}">{{ link.dir_name }}</a></td>
|
||||
<td><a href="{% url 'user_profile' link.username %}">{{ link.username|email2nickname }}</a></td>
|
||||
<td>--</td>
|
||||
<td>{{ link.view_cnt }}</td>
|
||||
<td>
|
||||
<span class="icon-trash op-icon vh rm-link" data-token={{ link.token }} data-type="upload" title="{% trans "Remove"%}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
<div id="download-links" class="hide">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="5%"><!--icon--></th>
|
||||
<th width="40%">{% trans "Name"%}</th>
|
||||
<th width="15%">{% trans "Created By"%}</th>
|
||||
<th width="15%">{% trans "Size"%}</th>
|
||||
<th width="12%">{% trans "Visits"%}</th>
|
||||
<th width="13%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% if fileshares %}
|
||||
{% for link in fileshares %}
|
||||
<tr>
|
||||
{% if link.s_type == 'd'%}
|
||||
<td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td>
|
||||
<td><a href="{% url 'repo' repo.id %}?p={{ link.path|urlencode }}">{{ link.filename }}</a></td>
|
||||
<td><a href="{% url 'user_profile' link.username %}">{{ link.username|email2nickname }}</a></td>
|
||||
{% else %}
|
||||
<td class="alc"><img src="{{ MEDIA_URL }}img/file/{{ link.filename|file_icon_filter }}" alt="{% trans "File"%}" /></td>
|
||||
<td><a href="{% url 'repo_view_file' repo.id %}?p={{ link.path|urlencode }}">{{ link.filename }}</a></td>
|
||||
<td><a href="{% url 'user_profile' link.username %}">{{ link.username|email2nickname }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ link.filesize|filesizeformat}}</td>
|
||||
<td>{{ link.view_cnt }}</td>
|
||||
<td>
|
||||
<span class="icon-trash op-icon vh rm-link" data-token={{ link.token }} data-type="download" title="{% trans "Remove"%}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$('#repo-basic-info-form input[name="history"]').change(function() {
|
||||
var value = $(this).attr('value'),
|
||||
days_input = $('#repo-basic-info-form input[name="days"]');
|
||||
if (value == 'full_history' || value == 'no_history') {
|
||||
days_input.attr('disabled', true).addClass('input-disabled');
|
||||
} else {
|
||||
days_input.attr('disabled', false).removeClass('input-disabled');
|
||||
}
|
||||
});
|
||||
|
||||
$('#repo-basic-info-form').submit(function() {
|
||||
var form = $(this),
|
||||
form_id = form.attr('id');
|
||||
var repo_name = $('[name="repo_name"]', form).val(),
|
||||
repo_desc = $('[name="repo_desc"]', form).val();
|
||||
|
||||
if (!$.trim(repo_name)) {
|
||||
apply_form_error(form_id, "{% trans "Name is required." %}");
|
||||
return false;
|
||||
}
|
||||
if (!$.trim(repo_desc)) {
|
||||
apply_form_error(form_id, "{% trans "Description is required." %}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var days;
|
||||
var value = $(this).find('input[name="history"]:checked').val();
|
||||
|
||||
if (value == 'partial_history') {
|
||||
days = $(this).find('input[name="days"]').val();
|
||||
} else if (value == 'full_history') {
|
||||
days = -1;
|
||||
} else {
|
||||
days = 0;
|
||||
}
|
||||
|
||||
var submit_btn = $(this).children('input[type="submit"]');
|
||||
disable(submit_btn);
|
||||
$.ajax({
|
||||
url: '{% url 'repo_change_basic_info' repo.id %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'repo_name': repo_name,
|
||||
'repo_desc': repo_desc,
|
||||
'days': days
|
||||
},
|
||||
success: function(data) {
|
||||
if (data['success']) {
|
||||
location.reload(true);
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText) {
|
||||
apply_form_error(form_id, $.parseJSON(jqXHR.responseText).error);
|
||||
} else {
|
||||
apply_form_error(form_id, "{% trans "Failed. Please check the network." %}");
|
||||
}
|
||||
enable(submit_btn);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#repo-owner-form').submit(function() {
|
||||
var form = $(this),
|
||||
form_id = form.attr('id'),
|
||||
new_owner = $('[name="repo_owner"]', form).val(),
|
||||
submit_btn = $('input[type="submit"]', form);
|
||||
|
||||
if (!$.trim(new_owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
disable(submit_btn);
|
||||
$.ajax({
|
||||
url: '{% url 'repo_transfer_owner' repo.id %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'repo_owner': new_owner
|
||||
},
|
||||
success: function(data) {
|
||||
if (data['success']) {
|
||||
location.href = '{% url 'myhome' %}';
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText) {
|
||||
apply_form_error(form_id, $.parseJSON(jqXHR.responseText).error);
|
||||
} else {
|
||||
apply_form_error(form_id, "{% trans "Failed. Please check the network." %}");
|
||||
}
|
||||
enable(submit_btn);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
$('#repo-change-passwd-form').submit(function() {
|
||||
var form = $(this),
|
||||
form_id = form.attr('id'),
|
||||
old_passwd, new_passwd, new_passwd_again;
|
||||
|
||||
old_passwd = $('input[name="old_passwd"]', form).val();
|
||||
new_passwd = $('input[name="new_passwd"]', form).val();
|
||||
new_passwd_again = $('input[name="new_passwd_again"]', form).val();
|
||||
|
||||
if (!$.trim(old_passwd)) {
|
||||
apply_form_error(form_id, "{% trans "Please enter the old password" %}");
|
||||
return false;
|
||||
}
|
||||
if (!$.trim(new_passwd)) {
|
||||
apply_form_error(form_id, "{% trans "Please enter the new password" %}");
|
||||
return false;
|
||||
}
|
||||
if ($.trim(new_passwd).length < {{repo_password_min_length}}) {
|
||||
apply_form_error(form_id, "{% trans "New password is too short" %}");
|
||||
return false;
|
||||
}
|
||||
if (!$.trim(new_passwd_again)) {
|
||||
apply_form_error(form_id, "{% trans "Please enter the new password again" %}");
|
||||
return false;
|
||||
}
|
||||
if ($.trim(new_passwd) != $.trim(new_passwd_again)) {
|
||||
apply_form_error(form_id, "{% trans "New passwords don't match" %}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var submit_btn = $(this).children('input[type="submit"]');
|
||||
disable(submit_btn);
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'repo_change_passwd' repo.id %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'old_passwd': old_passwd,
|
||||
'new_passwd': new_passwd,
|
||||
'new_passwd_again': new_passwd_again
|
||||
},
|
||||
success: function(data) {
|
||||
if (data['success']) {
|
||||
location.reload(true);
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText) {
|
||||
apply_form_error(form_id, $.parseJSON(jqXHR.responseText).error);
|
||||
} else {
|
||||
apply_form_error(form_id, "{% trans "Failed. Please check the network." %}");
|
||||
}
|
||||
enable(submit_btn);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
$('.side-textnav-tabs .tab').click(function() {
|
||||
var cur_tab = $(this),
|
||||
cur_tab_con = $($('a', cur_tab).attr('href'));
|
||||
|
||||
$('.side-textnav-tabs .tab').removeClass('tab-cur');
|
||||
$('.lib-setting .setting-item').addClass('hide');
|
||||
cur_tab.addClass('tab-cur');
|
||||
cur_tab_con.removeClass('hide')
|
||||
return false;
|
||||
});
|
||||
|
||||
{% if not repo.encrypted %}
|
||||
$('#shared-links .rm-link').click(function() {
|
||||
var op = $(this),
|
||||
link_token = op.data('token'),
|
||||
link_type = op.data('type'),
|
||||
ajax_url;
|
||||
|
||||
if (link_type == 'upload') {
|
||||
ajax_url = '{% url 'ajax_remove_shared_upload_link' %}';
|
||||
} else {
|
||||
ajax_url = '{% url 'ajax_remove_shared_link' %}';
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: ajax_url + '?t=' + e(link_token),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
op.parents('tr').remove();
|
||||
feedback("{% trans "Removed successfully." %}", 'success');
|
||||
},
|
||||
error: ajaxErrorHandler
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
239
seahub/templates/repo_share_manage.html
Normal file
239
seahub/templates/repo_share_manage.html
Normal file
@ -0,0 +1,239 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags group_avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab"><a href="{% url 'repo_basic_info' repo.id %}">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_transfer_owner' repo.id %}">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab"><a href="{% url 'repo_change_password' repo.id %}">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab"><a href="{% url 'repo_shared_link' repo.id %}">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
<li class="tab tab-cur"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Management" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "SubFolder Permission" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
<h3>{% trans "Sharing Management" %}</h3>
|
||||
<p>{% trans "View and manage all the share of this library." %}</p>
|
||||
|
||||
<div id="tabs" class="tab-tabs">
|
||||
<div class="hd ovhd">
|
||||
<ul class="tab-tabs-nav fleft">
|
||||
<li class="tab"><a href="#user-tab" class="a" id="user-tab">{% trans "User" %}</a></li>
|
||||
<li class="tab"><a href="#group-tab" class="a" id="group-tab">{% trans "Group" %}</a></li>
|
||||
</ul>
|
||||
<div class="fright">
|
||||
<button class="repo-share-btn"><img src="{{ MEDIA_URL }}img/add.png" alt="" class="add vam" /><span class="vam">{% trans "Share Library" %}</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="user-tab">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="40%">{% trans "Share To"%}</th>
|
||||
<th width="40%">{% trans "Permission"%}</th>
|
||||
<th width="20%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% if repo_share_user %}
|
||||
{% for share in repo_share_user %}
|
||||
<tr class="perm-item" data-to_user="{{ share.user }}">
|
||||
<td><a href="{% url 'user_profile' share.user %}">{{ share.user }}</a></td>
|
||||
<td>
|
||||
<div class="perm-change">
|
||||
{% if share.permission == 'rw' %}
|
||||
<span class="share-perm-cur-value">{% trans "Read-Write" %}</span>
|
||||
{% else %}
|
||||
<span class="share-perm-cur-value">{% trans "Read-Only" %}</span>
|
||||
{% endif %}
|
||||
<img src="{{MEDIA_URL}}img/edit_12.png" alt="{% trans "Edit"%}" title="{% trans "Edit"%}" class="perm-edit-icon cspt vh" />
|
||||
</div>
|
||||
<select class="perm-toggle-select hide">
|
||||
<option value="rw" {%if share.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Write" %}</option>
|
||||
<option value="r" {%if not share.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'repo_remove_share' %}?repo_id={{ share.repo_id }}&from={{ request.user.username|urlencode }}&to={{ share.user|urlencode }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
<div id="group-tab" class="hide">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="40%">{% trans "Share To"%}</th>
|
||||
<th width="40%">{% trans "Permission"%}</th>
|
||||
<th width="20%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% if repo_share_group %}
|
||||
{% for share in repo_share_group %}
|
||||
<tr class="perm-item" data-group_id="{{ share.group_id }}">
|
||||
<td><a href="{% url 'group_info' share.group_id%}">{{ share.group_name }}</a></td>
|
||||
<td>
|
||||
<div class="perm-change">
|
||||
{% if share.permission == 'rw' %}
|
||||
<span class="perm-cur-value">{% trans "Read-Write" %}</span>
|
||||
{% else %}
|
||||
<span class="perm-cur-value">{% trans "Read-Only" %}</span>
|
||||
{% endif %}
|
||||
<img src="{{MEDIA_URL}}img/edit_12.png" alt="{% trans "Edit"%}" title="{% trans "Edit"%}" class="perm-edit-icon cspt vh" />
|
||||
</div>
|
||||
<select class="perm-toggle-select hide">
|
||||
<option value="rw" {%if share.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Write" %}</option>
|
||||
<option value="r" {%if not share.permission == 'rw' %}selected="selected"{% endif %}>{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'repo_remove_share' %}?repo_id={{ share.repo_id }}&from={{ request.user.username|urlencode }}&gid={{ share.group_id }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% url 'share_repo' as repo_share_url %}
|
||||
{% with post_url=repo_share_url %}
|
||||
{% include "snippets/repo_share_form.html" %}
|
||||
{% endwith %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
|
||||
$(function () {
|
||||
$.ajax({
|
||||
url:'{% url 'get_contacts' %}',
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var share_list = [];
|
||||
var contacts = data['contacts'], contact_email, group_name, group_name_py;
|
||||
for (var i = 0, len = contacts.length; i < len; i++) {
|
||||
contact_email = contacts[i].email;
|
||||
share_list.push({value:contact_email, label:contact_email});
|
||||
}
|
||||
{% for group in request.user.joined_groups %}
|
||||
group_name = '{{ group.group_name }}';
|
||||
group_name_py = '{{ group.group_name|char2pinyin }}'
|
||||
share_list.push({value:group_name + group_name_py, label:group_name});
|
||||
{% endfor %}
|
||||
|
||||
$(".repo-share-btn").click(function() {
|
||||
var form = $("#repo-share-form"),
|
||||
hd = $('.hd', form),
|
||||
btn_ct = $(this).parents('td'),
|
||||
repo_name = btn_ct.attr('data-name');
|
||||
var grp_options_ct = $('#share-grp-options');
|
||||
if (!$.trim(grp_options_ct.html())) {
|
||||
var grp_options = '<ul class="option-list">';
|
||||
{% for group in request.user.joined_groups %}
|
||||
grp_options += '<li> <label class="checkbox-label"> <span class="checkbox"><input type="checkbox" name="grp" value="{{ group.group_name }}" class="checkbox-orig"/></span> {% grp_avatar group.id 20 %} <span class="checkbox-option">{{ group.group_name }}</span> </label> </li>';
|
||||
{% endfor %}
|
||||
grp_options += '</ul>';
|
||||
grp_options_ct.html(grp_options);
|
||||
}
|
||||
var contact_options_ct = $('#share-contact-options');
|
||||
if (!$.trim(contact_options_ct.html())) {
|
||||
var contact_options = '<ul class="option-list">';
|
||||
for (var i = 0, len = contacts.length; i < len; i++) {
|
||||
contact_email = contacts[i].email;
|
||||
contact_options += ' <li> <label class="checkbox-label"> <span class="checkbox"><input type="checkbox" name="contact" value="' + contact_email + '" class="checkbox-orig" /></span>' + contacts[i].avatar + ' <span class="checkbox-option">' + contact_email + '</span> </label> </li>';
|
||||
}
|
||||
contact_options += '</ul>';
|
||||
contact_options_ct.html(contact_options);
|
||||
}
|
||||
|
||||
$('.checkbox-orig', form).unbind().click(function() {
|
||||
$(this).parent().toggleClass('checkbox-checked');
|
||||
});
|
||||
$(".checkbox-label", form).unbind().hover(
|
||||
function() {
|
||||
$(this).addClass('hl');
|
||||
},
|
||||
function() {
|
||||
$(this).removeClass('hl');
|
||||
}
|
||||
);
|
||||
form.modal({appendTo: "#main", focus:false, containerCss:{"padding": 0}});
|
||||
$('[name="repo_id"]', form).val('{{repo.id}}');
|
||||
hd.html(hd.html().replace('%(lib_name)s', '<span class="op-target">' + repo_name + '</span>'));
|
||||
$('#repo-share-tabs').tabs();
|
||||
$('#simplemodal-container').css('height', 'auto');
|
||||
addAutocomplete('#email_or_group', '#repo-share-form', share_list);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//check before post
|
||||
$('#share-submit-btn').click(function() {
|
||||
var form = $("#repo-share-form"),
|
||||
cur_tab_id = $('.ui-tabs-selected a', form).attr('href'),
|
||||
post_data = '',
|
||||
input = $('[name="email_or_group"]', form);
|
||||
switch(cur_tab_id) {
|
||||
case '#share-enter':
|
||||
post_data = input.val();
|
||||
break;
|
||||
case '#share-grp-options':
|
||||
case '#share-contact-options':
|
||||
$(cur_tab_id + ' .checkbox-checked .checkbox-orig').each(function() {
|
||||
post_data += $(this).val() + ',';
|
||||
});
|
||||
input.val(post_data);
|
||||
}
|
||||
if (!post_data) {
|
||||
apply_form_error(form.attr('id'), "{% trans "Please enter emails or groups, or select some." %}");
|
||||
return false;
|
||||
}
|
||||
form.submit();
|
||||
disable($(this));
|
||||
});
|
||||
|
||||
{% include "repo_setting_extra_js.html" %}
|
||||
|
||||
$('.perm-toggle-select').on('change', function() {
|
||||
var select = $(this),
|
||||
perm_item = select.parents('.perm-item'),
|
||||
perm = select.val();
|
||||
|
||||
if (is_user_tab == true) {
|
||||
var to_user = perm_item.attr('data-to_user'),
|
||||
data = { repo_id: '{{repo.id}}', email_or_group: to_user, permission: perm },
|
||||
url = '{% url 'share_permission_admin' %}?share_type=' + 'personal';
|
||||
} else {
|
||||
var group_id = perm_item.attr('data-group_id'),
|
||||
data = { repo_id: '{{repo.id}}', email_or_group: group_id, permission: perm },
|
||||
url = '{% url 'share_permission_admin' %}?share_type=' + 'group';
|
||||
}
|
||||
|
||||
perm_toggle(select, data, url)
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
130
seahub/templates/repo_shared_link.html
Normal file
130
seahub/templates/repo_shared_link.html
Normal file
@ -0,0 +1,130 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab"><a href="{% url 'repo_basic_info' repo.id %}">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_transfer_owner' repo.id %}">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab"><a href="{% url 'repo_change_password' repo.id %}">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab tab-cur"><a href="{% url 'repo_shared_link' repo.id %}">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Management" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "SubFolder Permission" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
<div id="shared-links" class="setting-item">
|
||||
<h3>{% trans "Shared Links" %}</h3>
|
||||
<p>{% trans "View and manage all the shared links in this library." %}</p>
|
||||
<div id="tabs" class="tab-tabs">
|
||||
<ul class="tab-tabs-nav hd ovhd">
|
||||
<li class="tab"><a href="#upload-links" class="a">{% trans "Upload Links" %}</a></li>
|
||||
<li class="tab"><a href="#download-links" class="a">{% trans "Download Links" %}</a></li>
|
||||
</ul>
|
||||
<div id="upload-links">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="5%"><!--icon--></th>
|
||||
<th width="40%">{% trans "Name"%}</th>
|
||||
<th width="15%">{% trans "Created By"%}</th>
|
||||
<th width="15%">{% trans "Size"%}</th>
|
||||
<th width="12%">{% trans "Visits"%}</th>
|
||||
<th width="13%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% if uploadlinks %}
|
||||
{% for link in uploadlinks %}
|
||||
<tr>
|
||||
<td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td>
|
||||
<td><a href="{% url 'repo' repo.id %}?p={{ link.path|urlencode }}">{{ link.dir_name }}</a></td>
|
||||
<td><a href="{% url 'user_profile' link.username %}">{{ link.username|email2nickname }}</a></td>
|
||||
<td>--</td>
|
||||
<td>{{ link.view_cnt }}</td>
|
||||
<td>
|
||||
<span class="icon-trash op-icon vh rm-link" data-token={{ link.token }} data-type="upload" title="{% trans "Remove"%}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
<div id="download-links" class="hide">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="5%"><!--icon--></th>
|
||||
<th width="40%">{% trans "Name"%}</th>
|
||||
<th width="15%">{% trans "Created By"%}</th>
|
||||
<th width="15%">{% trans "Size"%}</th>
|
||||
<th width="12%">{% trans "Visits"%}</th>
|
||||
<th width="13%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% if fileshares %}
|
||||
{% for link in fileshares %}
|
||||
<tr>
|
||||
{% if link.s_type == 'd'%}
|
||||
<td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td>
|
||||
<td><a href="{% url 'repo' repo.id %}?p={{ link.path|urlencode }}">{{ link.filename }}</a></td>
|
||||
<td><a href="{% url 'user_profile' link.username %}">{{ link.username|email2nickname }}</a></td>
|
||||
{% else %}
|
||||
<td class="alc"><img src="{{ MEDIA_URL }}img/file/{{ link.filename|file_icon_filter }}" alt="{% trans "File"%}" /></td>
|
||||
<td><a href="{% url 'repo_view_file' repo.id %}?p={{ link.path|urlencode }}">{{ link.filename }}</a></td>
|
||||
<td><a href="{% url 'user_profile' link.username %}">{{ link.username|email2nickname }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ link.filesize|filesizeformat}}</td>
|
||||
<td>{{ link.view_cnt }}</td>
|
||||
<td>
|
||||
<span class="icon-trash op-icon vh rm-link" data-token={{ link.token }} data-type="download" title="{% trans "Remove"%}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$('#shared-links .rm-link').click(function() {
|
||||
var op = $(this),
|
||||
link_token = op.data('token'),
|
||||
link_type = op.data('type'),
|
||||
ajax_url;
|
||||
if (link_type == 'upload') {
|
||||
ajax_url = '{% url 'ajax_remove_shared_upload_link' %}';
|
||||
} else {
|
||||
ajax_url = '{% url 'ajax_remove_shared_link' %}';
|
||||
}
|
||||
$.ajax({
|
||||
url: ajax_url + '?t=' + e(link_token),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
op.parents('tr').remove();
|
||||
feedback("{% trans "Removed successfully." %}", 'success');
|
||||
},
|
||||
error: ajaxErrorHandler
|
||||
});
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
85
seahub/templates/repo_transfer_owner.html
Normal file
85
seahub/templates/repo_transfer_owner.html
Normal file
@ -0,0 +1,85 @@
|
||||
{% extends "myhome_base.html" %}
|
||||
|
||||
{% load i18n avatar_tags seahub_tags %}
|
||||
|
||||
{% block sub_title %}{{repo.name}} - {% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
#left-panel { position: relative; }
|
||||
.go-back { top:0; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_panel %}
|
||||
<a class="go-back" title="{% trans "Back to Library" %}" href="{% url 'repo' repo.id %}"><span class="icon-chevron-left"></span></a>
|
||||
<div class="side-textnav">
|
||||
<ul class="side-textnav-tabs">
|
||||
<li class="tab"><a href="{% url 'repo_basic_info' repo.id %}">{% trans "Basic Info" %}</a></li>
|
||||
<li class="tab tab-cur"><a href="{% url 'repo_transfer_owner' repo.id %}">{% trans "Transfer Ownership" %}</a></li>
|
||||
{% if repo.encrypted and repo.enc_version == 2 %}
|
||||
<li class="tab"><a href="{% url 'repo_change_password' repo.id %}">{% trans "Change Password" %}</a></li>
|
||||
{% endif %}
|
||||
{% if not repo.encrypted %}
|
||||
<li class="tab"><a href="{% url 'repo_shared_link' repo.id %}">{% trans "Shared Links" %}</a></li>
|
||||
{% endif %}
|
||||
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Management" %}</a></li>
|
||||
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "SubFolder Permission" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block right_panel %}
|
||||
<div class="lib-setting">
|
||||
<h2>{% trans "Library Settings" %}</h2>
|
||||
<div id="transfer-ownership" class="setting-item">
|
||||
<h3>{% trans "Transfer Ownership" %}</h3>
|
||||
<form id="repo-owner-form" action="" method="post" class="form">{% csrf_token %}
|
||||
<p>{% trans "Transfer this library to another user:" %}</p>
|
||||
<input type="text" name="repo_owner" value="" placeholder="{% trans "Email" %}" class="input" /><br />
|
||||
<p class="error hide"></p>
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
$('#repo-owner-form').submit(function() {
|
||||
var form = $(this),
|
||||
form_id = form.attr('id'),
|
||||
new_owner = $('[name="repo_owner"]', form).val(),
|
||||
submit_btn = $('input[type="submit"]', form);
|
||||
|
||||
if (!$.trim(new_owner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
disable(submit_btn);
|
||||
$.ajax({
|
||||
url: '{% url 'ajax_repo_transfer_owner' repo.id %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'repo_owner': new_owner
|
||||
},
|
||||
success: function(data) {
|
||||
if (data['success']) {
|
||||
location.href = '{% url 'myhome' %}';
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText) {
|
||||
apply_form_error(form_id, $.parseJSON(jqXHR.responseText).error);
|
||||
} else {
|
||||
apply_form_error(form_id, "{% trans "Failed. Please check the network." %}");
|
||||
}
|
||||
enable(submit_btn);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -83,10 +83,12 @@ urlpatterns = patterns('',
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/privshare/$', gen_private_file_share, name='gen_private_file_share'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/(?P<obj_id>[0-9a-f]{40})/$', repo_access_file, name='repo_access_file'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/(?P<obj_id>[0-9a-f]{40})/download/$', download_file, name='download_file'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/settings/$', repo_settings, name='repo_settings'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/basic_info/$', repo_change_basic_info, name='repo_change_basic_info'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/owner/$', repo_transfer_owner, name='repo_transfer_owner'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/passwd/$', repo_change_passwd, name='repo_change_passwd'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/setting/basic-info/$', repo_basic_info, name='repo_basic_info'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/setting/transfer-owner/$', repo_transfer_owner, name='repo_transfer_owner'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/setting/change-password/$', repo_change_password, name='repo_change_password'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/setting/shared-link/$', repo_shared_link, name='repo_shared_link'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/setting/share-manage/$', repo_share_manage, name='repo_share_manage'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/setting/folder-perm/$', repo_folder_perm, name='repo_folder_perm'),
|
||||
|
||||
### share file/dir, upload link ###
|
||||
url(r'^s/f/(?P<token>[a-f0-9]{10})/$', view_priv_shared_file, name="view_priv_shared_file"),
|
||||
@ -155,6 +157,15 @@ urlpatterns = patterns('',
|
||||
url(r'^ajax/space_and_traffic/$', space_and_traffic, name='space_and_traffic'),
|
||||
url(r'^ajax/my-shared-and-group-repos/$', my_shared_and_group_repos, name='my_shared_and_group_repos'),
|
||||
url(r'^ajax/events/$', events, name="events"),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/change-basic-info/$', ajax_repo_change_basic_info, name='ajax_repo_change_basic_info'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/transfer-owner/$', ajax_repo_transfer_owner, name='ajax_repo_transfer_owner'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/change-passwd/$', ajax_repo_change_passwd, name='ajax_repo_change_passwd'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/user-folder-permission/add/$', add_user_folder_permission, name='add_user_folder_permission'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/user-folder-permission/remove/$', remove_user_folder_permission, name='remove_user_folder_permission'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/user-folder-permission/toggle/$', toggle_user_folder_permission, name='toggle_user_folder_permission'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/group-folder-permission/add/$', add_group_folder_permission, name='add_group_folder_permission'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/group-folder-permission/remove/$', remove_group_folder_permission, name='remove_group_folder_permission'),
|
||||
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/setting/group-folder-permission/toggle/$', toggle_group_folder_permission, name='toggle_group_folder_permission'),
|
||||
|
||||
### Organizaion ###
|
||||
url(r'^pubinfo/libraries/$', pubrepo, name='pubrepo'),
|
||||
|
@ -1,10 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
import seaserv
|
||||
from seaserv import seafile_api
|
||||
from seahub.utils import EMPTY_SHA1
|
||||
|
||||
from seahub.utils import EMPTY_SHA1, is_valid_username
|
||||
from seahub.views import check_repo_access_permission
|
||||
|
||||
def list_dir_by_path(cmmt, path):
|
||||
if cmmt.root_id == EMPTY_SHA1:
|
||||
return []
|
||||
else:
|
||||
return seafile_api.list_dir_by_commit_and_path(cmmt.repo_id, cmmt.id, path)
|
||||
|
||||
|
||||
def check_user_folder_perm_args(request_user, repo_id, path, user, perm = None):
|
||||
if not seafile_api.get_repo(repo_id):
|
||||
return {'error': _(u'Library does not exist.'), 'status': 400}
|
||||
|
||||
if check_repo_access_permission(repo_id, request_user) != 'rw':
|
||||
return {'error': _('Permission denied'), 'status': 403}
|
||||
|
||||
if perm is not None:
|
||||
# add or toggle folder perm
|
||||
if seafile_api.get_dir_id_by_path(repo_id, path) is None:
|
||||
return {'error': _('Invalid path'), 'status': 400}
|
||||
|
||||
if perm != 'r' and perm != 'rw':
|
||||
return {'error': _('Invalid folder permission'), 'status': 400}
|
||||
|
||||
if not path.startswith('/'):
|
||||
return {'error': _('Path should start with "/"'), 'status': 400}
|
||||
|
||||
if path != '/' and path.endswith('/'):
|
||||
return {'error': _('Path should NOT ends with "/"'), 'status': 400}
|
||||
|
||||
if user and not is_valid_username(user):
|
||||
return {'error': _('Invalid username'), 'status': 400}
|
||||
|
||||
return {'success': True}
|
||||
|
||||
def check_group_folder_perm_args(request_user, repo_id, path, group_id, perm = None):
|
||||
if not seafile_api.get_repo(repo_id):
|
||||
return {'error': _(u'Library does not exist.'), 'status': 400}
|
||||
|
||||
if check_repo_access_permission(repo_id, request_user) != 'rw':
|
||||
return {'error': _('Permission denied'), 'status': 403}
|
||||
|
||||
if perm is not None:
|
||||
# add or toggle folder perm
|
||||
if seafile_api.get_dir_id_by_path(repo_id, path) is None:
|
||||
return {'error': _('Invalid path'), 'status': 400}
|
||||
|
||||
if perm != 'r' and perm != 'rw':
|
||||
return {'error': _('Invalid folder permission'), 'status': 400}
|
||||
|
||||
if not path.startswith('/'):
|
||||
return {'error': _('Path should start with "/"'), 'status': 400}
|
||||
|
||||
if path != '/' and path.endswith('/'):
|
||||
return {'error': _('Path should NOT ends with "/"'), 'status': 400}
|
||||
|
||||
if group_id and not seaserv.get_group(group_id):
|
||||
return {'error': _('Invalid group'), 'status': 400}
|
||||
|
||||
return {'success': True}
|
||||
|
@ -24,9 +24,9 @@ from django.views.decorators.http import condition
|
||||
import seaserv
|
||||
from seaserv import get_repo, get_commits, is_valid_filename, \
|
||||
seafserv_threaded_rpc, seafserv_rpc, is_repo_owner, check_permission, \
|
||||
is_passwd_set, get_file_size, edit_repo, \
|
||||
get_session_info, set_repo_history_limit, get_commit, \
|
||||
MAX_DOWNLOAD_DIR_SIZE, send_message, ccnet_threaded_rpc
|
||||
is_passwd_set, get_file_size, get_group, get_session_info, get_commit, \
|
||||
MAX_DOWNLOAD_DIR_SIZE, send_message, ccnet_threaded_rpc, \
|
||||
get_personal_groups_by_user
|
||||
from seaserv import seafile_api
|
||||
from pysearpc import SearpcError
|
||||
|
||||
@ -42,18 +42,17 @@ from seahub.options.models import UserOptions, CryptoOptionNotSetError
|
||||
from seahub.profile.models import Profile
|
||||
from seahub.share.models import FileShare, PrivateFileDirShare, \
|
||||
UploadLinkShare
|
||||
from seahub.forms import RepoPassowrdForm, RepoSettingForm
|
||||
from seahub.forms import RepoPassowrdForm
|
||||
from seahub.utils import render_permission_error, render_error, list_to_string, \
|
||||
get_fileserver_root, gen_shared_upload_link, \
|
||||
get_fileserver_root, gen_shared_upload_link, is_org_context, \
|
||||
gen_dir_share_link, gen_file_share_link, get_repo_last_modify, \
|
||||
calculate_repos_last_modify, get_file_type_and_ext, get_user_repos, \
|
||||
EMPTY_SHA1, normalize_file_path, is_valid_username, \
|
||||
EMPTY_SHA1, normalize_file_path, gen_file_upload_url, \
|
||||
get_file_revision_id_size, get_ccnet_server_addr_port, \
|
||||
gen_file_get_url, string2list, MAX_INT, IS_EMAIL_CONFIGURED, \
|
||||
gen_file_upload_url, \
|
||||
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, is_org_context
|
||||
user_traffic_over_limit
|
||||
from seahub.utils.paginator import get_page_range
|
||||
from seahub.utils.star import get_dir_starred_files
|
||||
from seahub.views.modules import MOD_PERSONAL_WIKI, enable_mod_for_user, \
|
||||
@ -96,6 +95,16 @@ def get_system_default_repo_id():
|
||||
logger.error(e)
|
||||
return None
|
||||
|
||||
def check_folder_permission(repo_id, path, username):
|
||||
repo_owner = seafile_api.get_repo_owner(repo_id)
|
||||
if username == repo_owner:
|
||||
return 'rw'
|
||||
|
||||
if path != '/' and path.endswith('/'):
|
||||
path = path.rstrip('/')
|
||||
|
||||
return seafile_api.check_permission_by_path(repo_id, path, username)
|
||||
|
||||
def check_repo_access_permission(repo_id, user):
|
||||
"""Check repo access permission of a user, always return 'rw' when repo is
|
||||
system repo and user is admin.
|
||||
@ -409,27 +418,34 @@ def repo_online_gc(request, repo_id):
|
||||
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
@login_required
|
||||
def repo_settings(request, repo_id):
|
||||
"""List and change library settings.
|
||||
"""
|
||||
username = request.user.username
|
||||
|
||||
def can_access_repo_setting(request, repo_id, username):
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
return (False, None)
|
||||
|
||||
# no settings for virtual repo
|
||||
if ENABLE_SUB_LIBRARY and repo.is_virtual:
|
||||
raise Http404
|
||||
return (False, None)
|
||||
|
||||
# check permission
|
||||
if is_org_context(request):
|
||||
repo_owner = seafile_api.get_org_repo_owner(repo.id)
|
||||
repo_owner = seafile_api.get_org_repo_owner(repo_id)
|
||||
else:
|
||||
repo_owner = seafile_api.get_repo_owner(repo.id)
|
||||
repo_owner = seafile_api.get_repo_owner(repo_id)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
return (False, None)
|
||||
|
||||
return (True, repo)
|
||||
|
||||
@login_required
|
||||
def repo_basic_info(request, repo_id):
|
||||
"""List and change library basic info.
|
||||
"""
|
||||
username = request.user.username
|
||||
can_access, repo = can_access_repo_setting(request, repo_id, username)
|
||||
|
||||
if not can_access:
|
||||
raise Http404
|
||||
|
||||
history_limit = seaserv.get_repo_history_limit(repo.id)
|
||||
@ -450,6 +466,57 @@ def repo_settings(request, repo_id):
|
||||
if history_limit <= 0:
|
||||
days_enabled = False
|
||||
|
||||
return render_to_response('repo_basic_info.html', {
|
||||
'repo': repo,
|
||||
'history_limit': history_limit if history_limit > 0 else '',
|
||||
'full_history_checked': full_history_checked,
|
||||
'no_history_checked': no_history_checked,
|
||||
'partial_history_checked': partial_history_checked,
|
||||
'full_history_enabled': full_history_enabled,
|
||||
'no_history_enabled': no_history_enabled,
|
||||
'partial_history_enabled': partial_history_enabled,
|
||||
'days_enabled': days_enabled,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def repo_transfer_owner(request, repo_id):
|
||||
"""Transfer repo owner.
|
||||
"""
|
||||
username = request.user.username
|
||||
can_access, repo = can_access_repo_setting(request, repo_id, username)
|
||||
|
||||
if not can_access:
|
||||
raise Http404
|
||||
|
||||
return render_to_response('repo_transfer_owner.html', {
|
||||
'repo': repo,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def repo_change_password(request, repo_id):
|
||||
"""Change library password.
|
||||
"""
|
||||
username = request.user.username
|
||||
can_access, repo = can_access_repo_setting(request, repo_id, username)
|
||||
|
||||
if not can_access:
|
||||
raise Http404
|
||||
|
||||
return render_to_response('repo_change_password.html', {
|
||||
'repo': repo,
|
||||
'repo_password_min_length': REPO_PASSWORD_MIN_LENGTH,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def repo_shared_link(request, repo_id):
|
||||
"""List and change library shared links.
|
||||
"""
|
||||
username = request.user.username
|
||||
can_access, repo = can_access_repo_setting(request, repo_id, username)
|
||||
|
||||
if not can_access:
|
||||
raise Http404
|
||||
|
||||
# download links
|
||||
fileshares = FileShare.objects.filter(repo_id=repo_id)
|
||||
p_fileshares = []
|
||||
@ -493,178 +560,88 @@ def repo_settings(request, repo_id):
|
||||
link.shared_link = gen_shared_upload_link(link.token)
|
||||
p_uploadlinks.append(link)
|
||||
|
||||
return render_to_response('repo_settings.html', {
|
||||
return render_to_response('repo_shared_link.html', {
|
||||
'repo': repo,
|
||||
'repo_owner': repo_owner,
|
||||
'history_limit': history_limit if history_limit > 0 else '',
|
||||
'full_history_checked': full_history_checked,
|
||||
'no_history_checked': no_history_checked,
|
||||
'partial_history_checked': partial_history_checked,
|
||||
'full_history_enabled': full_history_enabled,
|
||||
'no_history_enabled': no_history_enabled,
|
||||
'partial_history_enabled': partial_history_enabled,
|
||||
'days_enabled': days_enabled,
|
||||
'repo_password_min_length': REPO_PASSWORD_MIN_LENGTH,
|
||||
'fileshares': p_fileshares,
|
||||
'uploadlinks': p_uploadlinks,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required_ajax
|
||||
def repo_change_basic_info(request, repo_id):
|
||||
"""Handle post request to change library basic info.
|
||||
@login_required
|
||||
def repo_share_manage(request, repo_id):
|
||||
"""Manage share of this library.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
can_access, repo = can_access_repo_setting(request, repo_id, username)
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
if not can_access:
|
||||
raise Http404
|
||||
|
||||
# no settings for virtual repo
|
||||
if ENABLE_SUB_LIBRARY and repo.is_virtual:
|
||||
raise Http404
|
||||
|
||||
# check permission
|
||||
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)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
raise Http404
|
||||
|
||||
form = RepoSettingForm(request.POST)
|
||||
if not form.is_valid():
|
||||
return HttpResponse(json.dumps({
|
||||
'error': str(form.errors.values()[0])
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
repo_name = form.cleaned_data['repo_name']
|
||||
repo_desc = form.cleaned_data['repo_desc']
|
||||
days = form.cleaned_data['days']
|
||||
|
||||
# Edit library info (name, descryption).
|
||||
if repo.name != repo_name or repo.desc != repo_desc:
|
||||
if not edit_repo(repo_id, repo_name, repo_desc, username):
|
||||
err_msg = _(u'Failed to edit library information.')
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=500, content_type=content_type)
|
||||
|
||||
# set library history
|
||||
if days is not None and ENABLE_REPO_HISTORY_SETTING:
|
||||
res = set_repo_history_limit(repo_id, days)
|
||||
if res != 0:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _(u'Failed to save settings on server')
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
messages.success(request, _(u'Settings saved.'))
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def repo_transfer_owner(request, repo_id):
|
||||
"""Handle post request to transfer library owner.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# check permission
|
||||
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)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
raise Http404
|
||||
|
||||
# check POST arg
|
||||
repo_owner = request.POST.get('repo_owner', '').lower()
|
||||
if not is_valid_username(repo_owner):
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('Username %s is not valid.') % repo_owner,
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
try:
|
||||
User.objects.get(email=repo_owner)
|
||||
except User.DoesNotExist:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('User %s is not found.') % repo_owner,
|
||||
}), status=400, content_type=content_type)
|
||||
# sharing management
|
||||
repo_share_user = []
|
||||
repo_share_group = []
|
||||
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
if not seaserv.ccnet_threaded_rpc.org_user_exists(org_id, repo_owner):
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('User %s is not in current organization.') %
|
||||
repo_owner,}), status=400, content_type=content_type)
|
||||
|
||||
if repo_owner and repo_owner != username:
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
seafile_api.set_org_repo_owner(org_id, repo_id, repo_owner)
|
||||
else:
|
||||
if ccnet_threaded_rpc.get_orgs_by_user(repo_owner):
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('Can not transfer library to organization user %s.') % repo_owner,
|
||||
}), status=400, content_type=content_type)
|
||||
else:
|
||||
seafile_api.set_repo_owner(repo_id, repo_owner)
|
||||
|
||||
messages.success(request,
|
||||
_(u'Library %(repo_name)s has been transfered to %(new_owner)s.') %
|
||||
{'repo_name': repo.name, 'new_owner': repo_owner})
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def repo_change_passwd(request, repo_id):
|
||||
"""Handle ajax post request to change library password.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# check permission
|
||||
if is_org_context(request):
|
||||
repo_owner = seafile_api.get_org_repo_owner(repo.id)
|
||||
repo_share_user = seafile_api.get_org_share_out_repo_list(org_id, username, -1, -1)
|
||||
repo_share_group = seafserv_threaded_rpc.get_org_group_repos_by_owner(org_id, username)
|
||||
else:
|
||||
repo_owner = seafile_api.get_repo_owner(repo.id)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('Faied to change password, you are not owner.')}),
|
||||
status=400, content_type=content_type)
|
||||
repo_share_user = seafile_api.get_share_out_repo_list(username, -1, -1)
|
||||
repo_share_group = seaserv.get_group_repos_by_owner(username)
|
||||
|
||||
old_passwd = request.POST.get('old_passwd', '')
|
||||
new_passwd = request.POST.get('new_passwd', '')
|
||||
try:
|
||||
seafile_api.change_repo_passwd(repo_id, old_passwd, new_passwd, username)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': e.msg,
|
||||
}), status=400, content_type=content_type)
|
||||
repo_share_user = filter(lambda i: i.repo_id == repo_id, repo_share_user)
|
||||
repo_share_group = filter(lambda i: i.repo_id == repo_id, repo_share_group)
|
||||
for share in repo_share_group:
|
||||
share.group_name = get_group(share.group_id).group_name
|
||||
|
||||
messages.success(request, _(u'Successfully updated the password of Library %(repo_name)s.') %
|
||||
{'repo_name': repo.name})
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
return render_to_response('repo_share_manage.html', {
|
||||
'repo': repo,
|
||||
'repo_share_user': repo_share_user,
|
||||
'repo_share_group': repo_share_group,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def repo_folder_perm(request, repo_id):
|
||||
"""Manage folder permmission of this library.
|
||||
"""
|
||||
username = request.user.username
|
||||
can_access, repo = can_access_repo_setting(request, repo_id, username)
|
||||
|
||||
if not can_access:
|
||||
raise Http404
|
||||
|
||||
# for user folder permission
|
||||
user_folder_perms = seafile_api.list_folder_user_perm_by_repo(repo_id)
|
||||
user_folder_perms.reverse()
|
||||
|
||||
for folder_perm in user_folder_perms:
|
||||
folder_path = folder_perm.path
|
||||
folder_perm.folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(folder_path)
|
||||
if folder_path == '/':
|
||||
folder_perm.folder_name = _(u'Root Directory')
|
||||
else:
|
||||
folder_perm.folder_name = os.path.basename(folder_path)
|
||||
|
||||
# for group folder permission
|
||||
group_folder_perms = seafile_api.list_folder_group_perm_by_repo(repo_id)
|
||||
group_folder_perms.reverse()
|
||||
|
||||
for folder_perm in group_folder_perms:
|
||||
folder_path = folder_perm.path
|
||||
folder_perm.folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(folder_path)
|
||||
if folder_path == '/':
|
||||
folder_perm.folder_name = _(u'Root Directory')
|
||||
else:
|
||||
folder_perm.folder_name = os.path.basename(folder_path)
|
||||
folder_perm.group_name = get_group(folder_perm.group_id).group_name
|
||||
|
||||
contacts = Contact.objects.get_contacts_by_user(username)
|
||||
|
||||
return render_to_response('repo_folder_perm.html', {
|
||||
'repo': repo,
|
||||
'user_folder_perms': user_folder_perms,
|
||||
'group_folder_perms': group_folder_perms,
|
||||
'contacts': contacts,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def upload_error_msg (code):
|
||||
err_msg = _(u'Internal Server Error')
|
||||
@ -1359,10 +1336,6 @@ def repo_revert_file (request, repo_id):
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# perm check
|
||||
if check_repo_access_permission(repo.id, request.user) is None:
|
||||
raise Http404
|
||||
|
||||
commit_id = request.GET.get('commit')
|
||||
path = request.GET.get('p')
|
||||
from_page = request.GET.get('from')
|
||||
@ -1370,6 +1343,14 @@ def repo_revert_file (request, repo_id):
|
||||
if not (commit_id and path and from_page):
|
||||
return render_error(request, _(u"Invalid arguments"))
|
||||
|
||||
# perm check
|
||||
if check_folder_permission(repo.id, path, request.user.username) != 'rw':
|
||||
next = request.META.get('HTTP_REFERER', None)
|
||||
if not next:
|
||||
next = settings.SITE_ROOT
|
||||
messages.error(request, _("Permission denied"))
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
try:
|
||||
ret = seafserv_threaded_rpc.revert_file (repo_id, commit_id,
|
||||
path.encode('utf-8'), request.user.username)
|
||||
@ -1403,16 +1384,20 @@ def repo_revert_dir (request, repo_id):
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# perm check
|
||||
if check_repo_access_permission(repo.id, request.user) is None:
|
||||
raise Http404
|
||||
|
||||
commit_id = request.GET.get('commit')
|
||||
path = request.GET.get('p')
|
||||
|
||||
if not (commit_id and path):
|
||||
return render_error(request, _(u"Invalid arguments"))
|
||||
|
||||
# perm check
|
||||
if check_folder_permission(repo.id, path, request.user.username) != 'rw':
|
||||
next = request.META.get('HTTP_REFERER', None)
|
||||
if not next:
|
||||
next = settings.SITE_ROOT
|
||||
messages.error(request, _("Permission denied"))
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
try:
|
||||
ret = seafserv_threaded_rpc.revert_dir (repo_id, commit_id,
|
||||
path.encode('utf-8'), request.user.username)
|
||||
|
@ -10,18 +10,20 @@ from django.template import RequestContext
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.http import urlquote
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.contrib import messages
|
||||
|
||||
import seaserv
|
||||
from seaserv import seafile_api, seafserv_rpc, is_passwd_set, \
|
||||
get_related_users_by_repo, get_related_users_by_org_repo, \
|
||||
CALC_SHARE_USAGE, seafserv_threaded_rpc, ccnet_threaded_rpc, \
|
||||
get_user_quota_usage, get_user_share_usage
|
||||
get_user_quota_usage, get_user_share_usage, edit_repo, \
|
||||
set_repo_history_limit
|
||||
from pysearpc import SearpcError
|
||||
|
||||
from seahub.auth.decorators import login_required_ajax
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.forms import RepoNewDirentForm, RepoRenameDirentForm, \
|
||||
RepoCreateForm, SharedRepoCreateForm
|
||||
RepoCreateForm, SharedRepoCreateForm, RepoSettingForm
|
||||
from seahub.options.models import UserOptions, CryptoOptionNotSetError
|
||||
from seahub.notifications.models import UserNotification
|
||||
from seahub.notifications.views import add_notice_from_info
|
||||
@ -31,18 +33,20 @@ from seahub.signals import upload_file_successful, repo_created, repo_deleted
|
||||
from seahub.views import get_repo_dirents, validate_owner, \
|
||||
check_repo_access_permission, get_unencry_rw_repos_by_user, \
|
||||
get_system_default_repo_id, get_diff, group_events_data, \
|
||||
get_owned_repo_list
|
||||
|
||||
get_owned_repo_list, check_folder_permission
|
||||
from seahub.views.repo import get_nav_path, get_fileshare, get_dir_share_link, \
|
||||
get_uploadlink, get_dir_shared_upload_link
|
||||
import seahub.settings as settings
|
||||
from seahub.settings import ENABLE_THUMBNAIL, THUMBNAIL_ROOT, \
|
||||
THUMBNAIL_DEFAULT_SIZE
|
||||
THUMBNAIL_DEFAULT_SIZE, ENABLE_SUB_LIBRARY, ENABLE_REPO_HISTORY_SETTING
|
||||
from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
|
||||
gen_block_get_url, TRAFFIC_STATS_ENABLED, get_user_traffic_stat,\
|
||||
new_merge_with_no_conflict, get_commit_before_new_merge, \
|
||||
get_repo_last_modify, gen_file_upload_url, is_org_context, \
|
||||
get_org_user_events, get_user_events, get_file_type_and_ext
|
||||
get_org_user_events, get_user_events, get_file_type_and_ext, \
|
||||
is_valid_username
|
||||
from seahub.utils.repo import check_group_folder_perm_args, \
|
||||
check_user_folder_perm_args
|
||||
from seahub.utils.star import star_file, unstar_file
|
||||
from seahub.base.accounts import User
|
||||
from seahub.utils.file_types import IMAGE
|
||||
@ -301,7 +305,7 @@ def list_dir(request, repo_id):
|
||||
'file_list': file_list,
|
||||
'dirent_more': dirent_more,
|
||||
'more_start': more_start,
|
||||
'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
|
||||
'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
|
||||
'sub_lib_enabled': sub_lib_enabled,
|
||||
'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
|
||||
'current_commit': head_commit,
|
||||
@ -384,7 +388,7 @@ def list_dir_more(request, repo_id):
|
||||
'server_crypto': server_crypto,
|
||||
'dir_list': dir_list,
|
||||
'file_list': file_list,
|
||||
'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
|
||||
'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
|
||||
'sub_lib_enabled': sub_lib_enabled,
|
||||
'ENABLE_THUMBNAIL': ENABLE_THUMBNAIL,
|
||||
}
|
||||
@ -393,7 +397,6 @@ def list_dir_more(request, repo_id):
|
||||
return HttpResponse(json.dumps({'html': html, 'dirent_more': dirent_more, 'more_start': more_start}),
|
||||
content_type=content_type)
|
||||
|
||||
|
||||
def new_dirent_common(func):
|
||||
"""Decorator for common logic in creating directory and file.
|
||||
"""
|
||||
@ -410,9 +413,16 @@ def new_dirent_common(func):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# arguments checking
|
||||
parent_dir = request.GET.get('parent_dir', None)
|
||||
if not parent_dir:
|
||||
result['error'] = _('Argument missing')
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
||||
if check_folder_permission(repo.id, parent_dir, username) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
@ -426,13 +436,6 @@ def new_dirent_common(func):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# arguments checking
|
||||
parent_dir = request.GET.get('parent_dir', None)
|
||||
if not parent_dir:
|
||||
result['error'] = _('Argument missing')
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# rename duplicate name
|
||||
dirent_name = check_filename_with_rename(repo.id, parent_dir,
|
||||
dirent_name)
|
||||
@ -497,10 +500,11 @@ def rename_dirent(request, repo_id):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
# argument checking
|
||||
parent_dir = request.GET.get('parent_dir', None)
|
||||
if not parent_dir:
|
||||
result['error'] = _('Argument missing')
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# form validation
|
||||
@ -513,17 +517,25 @@ def rename_dirent(request, repo_id):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
full_path = os.path.join(parent_dir, oldname)
|
||||
if seafile_api.get_dir_id_by_path(repo.id, full_path) is not None:
|
||||
# when dirent is a dir, check current dir perm
|
||||
if check_folder_permission(repo.id, full_path, username) != 'rw':
|
||||
err_msg = _('Permission denied')
|
||||
return HttpResponse(json.dumps({'error': err_msg}), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
if seafile_api.get_file_id_by_path(repo.id, full_path) is not None:
|
||||
# when dirent is a file, check parent dir perm
|
||||
if check_folder_permission(repo.id, parent_dir, username) != 'rw':
|
||||
err_msg = _('Permission denied')
|
||||
return HttpResponse(json.dumps({'error': err_msg}), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
if newname == oldname:
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
# argument checking
|
||||
parent_dir = request.GET.get('parent_dir', None)
|
||||
if not parent_dir:
|
||||
result['error'] = _('Argument missing')
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# rename duplicate name
|
||||
newname = check_filename_with_rename(repo_id, parent_dir, newname)
|
||||
|
||||
@ -551,13 +563,6 @@ def delete_dirent(request, repo_id):
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=400, content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
||||
err_msg = _(u'Permission denied.')
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=403, content_type=content_type)
|
||||
|
||||
# argument checking
|
||||
parent_dir = request.GET.get("parent_dir", None)
|
||||
dirent_name = request.GET.get("name", None)
|
||||
@ -566,6 +571,23 @@ def delete_dirent(request, repo_id):
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=400, content_type=content_type)
|
||||
|
||||
full_path = os.path.join(parent_dir, dirent_name)
|
||||
username = request.user.username
|
||||
|
||||
if seafile_api.get_dir_id_by_path(repo.id, full_path) is not None:
|
||||
# when dirent is a dir, check current dir perm
|
||||
if check_folder_permission(repo.id, full_path, username) != 'rw':
|
||||
err_msg = _('Permission denied')
|
||||
return HttpResponse(json.dumps({'error': err_msg}), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
if seafile_api.get_file_id_by_path(repo.id, full_path) is not None:
|
||||
# when dirent is a file, check parent dir perm
|
||||
if check_folder_permission(repo.id, parent_dir, username) != 'rw':
|
||||
err_msg = _('Permission denied')
|
||||
return HttpResponse(json.dumps({'error': err_msg}), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
# delete file/dir
|
||||
try:
|
||||
seafile_api.del_file(repo_id, parent_dir, dirent_name, username)
|
||||
@ -590,13 +612,6 @@ def delete_dirents(request, repo_id):
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=400, content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
||||
err_msg = _(u'Permission denied.')
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=403, content_type=content_type)
|
||||
|
||||
# argument checking
|
||||
parent_dir = request.GET.get("parent_dir")
|
||||
dirents_names = request.POST.getlist('dirents_names')
|
||||
@ -605,6 +620,13 @@ def delete_dirents(request, repo_id):
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=400, content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_folder_permission(repo.id, parent_dir, username) != 'rw':
|
||||
err_msg = _(u'Permission denied.')
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=403, content_type=content_type)
|
||||
|
||||
deleted = []
|
||||
undeleted = []
|
||||
for dirent_name in dirents_names:
|
||||
@ -634,14 +656,6 @@ def copy_move_common(func):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
|
||||
# arguments validation
|
||||
path = request.GET.get('path')
|
||||
obj_name = request.GET.get('obj_name')
|
||||
@ -653,6 +667,13 @@ def copy_move_common(func):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_folder_permission(repo.id, path, username) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
# check file path
|
||||
if len(dst_path+obj_name) > settings.MAX_PATH:
|
||||
result['error'] = _('Destination path is too long.')
|
||||
@ -737,8 +758,17 @@ def cp_file(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
||||
def mv_dir(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
|
||||
src_dir = os.path.join(src_path, obj_name)
|
||||
|
||||
# permission checking
|
||||
dst_repo_owner = seafile_api.get_repo_owner(dst_repo_id)
|
||||
if check_folder_permission(src_repo_id, src_dir, username) != 'rw' or \
|
||||
check_folder_permission(dst_repo_id, dst_path, dst_repo_owner) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
if dst_path.startswith(src_dir + '/'):
|
||||
error_msg = _(u'Can not move directory %(src)s to its subdirectory %(des)s') \
|
||||
% {'src': src_dir, 'des': dst_path}
|
||||
@ -775,6 +805,14 @@ def cp_dir(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
# permission checking
|
||||
dst_repo_owner = seafile_api.get_repo_owner(dst_repo_id)
|
||||
if check_folder_permission(src_repo_id, src_path, username) != 'rw' or \
|
||||
check_folder_permission(dst_repo_id, dst_path, dst_repo_owner) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
src_dir = os.path.join(src_path, obj_name)
|
||||
if dst_path.startswith(src_dir):
|
||||
error_msg = _(u'Can not copy directory %(src)s to its subdirectory %(des)s') \
|
||||
@ -825,13 +863,6 @@ def dirents_copy_move_common(func):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
# arguments validation
|
||||
parent_dir = request.GET.get('parent_dir')
|
||||
obj_file_names = request.POST.getlist('file_names')
|
||||
@ -844,6 +875,13 @@ def dirents_copy_move_common(func):
|
||||
return HttpResponse(json.dumps(result), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
# permission checking
|
||||
username = request.user.username
|
||||
if check_folder_permission(repo.id, parent_dir, username) != 'rw':
|
||||
result['error'] = _('Permission denied')
|
||||
return HttpResponse(json.dumps(result), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
# check file path
|
||||
for obj_name in obj_file_names + obj_dir_names:
|
||||
if len(dst_path+obj_name) > settings.MAX_PATH:
|
||||
@ -870,6 +908,9 @@ def dirents_copy_move_common(func):
|
||||
def mv_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj_dir_names, username):
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
failed = []
|
||||
allowed_dirs = []
|
||||
dst_repo_owner = seafile_api.get_repo_owner(dst_repo_id)
|
||||
|
||||
for obj_name in obj_dir_names:
|
||||
src_dir = os.path.join(src_path, obj_name)
|
||||
@ -878,11 +919,18 @@ def mv_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
|
||||
% {'src': src_dir, 'des': dst_path}
|
||||
result['error'] = error_msg
|
||||
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
||||
|
||||
|
||||
# permission checking
|
||||
if check_folder_permission(src_repo_id, obj_name, username) != 'rw' or \
|
||||
check_folder_permission(dst_repo_id, dst_path, dst_repo_owner) != 'rw':
|
||||
failed.append(obj_name)
|
||||
else:
|
||||
allowed_dirs.append(obj_name)
|
||||
|
||||
success = []
|
||||
failed = []
|
||||
url = None
|
||||
for obj_name in obj_file_names + obj_dir_names:
|
||||
|
||||
for obj_name in obj_file_names + allowed_dirs:
|
||||
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
||||
try:
|
||||
res = seafile_api.move_file(src_repo_id, src_path, obj_name,
|
||||
@ -907,6 +955,10 @@ def cp_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
failed = []
|
||||
allowed_dirs = []
|
||||
dst_repo_owner = seafile_api.get_repo_owner(dst_repo_id)
|
||||
|
||||
for obj_name in obj_dir_names:
|
||||
src_dir = os.path.join(src_path, obj_name)
|
||||
if dst_path.startswith(src_dir):
|
||||
@ -914,11 +966,18 @@ def cp_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
|
||||
% {'src': src_dir, 'des': dst_path}
|
||||
result['error'] = error_msg
|
||||
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
||||
|
||||
|
||||
# permission checking
|
||||
if check_folder_permission(src_repo_id, obj_name, username) != 'rw' or \
|
||||
check_folder_permission(dst_repo_id, dst_path, dst_repo_owner) != 'rw':
|
||||
failed.append(obj_name)
|
||||
else:
|
||||
allowed_dirs.append(obj_name)
|
||||
|
||||
success = []
|
||||
failed = []
|
||||
url = None
|
||||
for obj_name in obj_file_names + obj_dir_names:
|
||||
|
||||
for obj_name in obj_file_names + allowed_dirs:
|
||||
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
||||
try:
|
||||
res = seafile_api.copy_file(src_repo_id, src_path, obj_name,
|
||||
@ -1596,17 +1655,29 @@ def get_file_op_url(request, repo_id):
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
op_type = request.GET.get('op_type') # value can be 'upload', 'update', 'upload-blks', 'update-blks'
|
||||
if not op_type:
|
||||
path = request.GET.get('path')
|
||||
if not (op_type and path):
|
||||
err_msg = _(u'Argument missing')
|
||||
return HttpResponse(json.dumps({"error": err_msg}), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
repo = get_repo(repo_id)
|
||||
if not repo:
|
||||
err_msg = _(u'Library does not exist')
|
||||
return HttpResponse(json.dumps({"error": err_msg}), status=400,
|
||||
content_type=content_type)
|
||||
|
||||
username = request.user.username
|
||||
# permission checking
|
||||
if check_folder_permission(repo.id, path, username) != 'rw':
|
||||
err_msg = _(u'Permission denied')
|
||||
return HttpResponse(json.dumps({"error": err_msg}), status=403,
|
||||
content_type=content_type)
|
||||
|
||||
url = ''
|
||||
if check_repo_access_permission(repo_id, request.user) == 'rw':
|
||||
token = seafile_api.get_fileserver_access_token(repo_id, 'dummy',
|
||||
op_type, username)
|
||||
url = gen_file_upload_url(token, op_type + '-aj')
|
||||
token = seafile_api.get_fileserver_access_token(repo_id, 'dummy',
|
||||
op_type, username)
|
||||
url = gen_file_upload_url(token, op_type + '-aj')
|
||||
|
||||
return HttpResponse(json.dumps({"url": url}), content_type=content_type)
|
||||
|
||||
@ -1859,3 +1930,355 @@ def events(request):
|
||||
'events_more': events_more,
|
||||
'new_start': start}),
|
||||
content_type='application/json; charset=utf-8')
|
||||
|
||||
@login_required_ajax
|
||||
def ajax_repo_change_basic_info(request, repo_id):
|
||||
"""Handle post request to change library basic info.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# no settings for virtual repo
|
||||
if ENABLE_SUB_LIBRARY and repo.is_virtual:
|
||||
raise Http404
|
||||
|
||||
# check permission
|
||||
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)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
raise Http404
|
||||
|
||||
form = RepoSettingForm(request.POST)
|
||||
if not form.is_valid():
|
||||
return HttpResponse(json.dumps({
|
||||
'error': str(form.errors.values()[0])
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
repo_name = form.cleaned_data['repo_name']
|
||||
repo_desc = form.cleaned_data['repo_desc']
|
||||
days = form.cleaned_data['days']
|
||||
|
||||
# Edit library info (name, descryption).
|
||||
if repo.name != repo_name or repo.desc != repo_desc:
|
||||
if not edit_repo(repo_id, repo_name, repo_desc, username):
|
||||
err_msg = _(u'Failed to edit library information.')
|
||||
return HttpResponse(json.dumps({'error': err_msg}),
|
||||
status=500, content_type=content_type)
|
||||
|
||||
# set library history
|
||||
if days is not None and ENABLE_REPO_HISTORY_SETTING:
|
||||
res = set_repo_history_limit(repo_id, days)
|
||||
if res != 0:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _(u'Failed to save settings on server')
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
messages.success(request, _(u'Settings saved.'))
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def ajax_repo_transfer_owner(request, repo_id):
|
||||
"""Handle post request to transfer library owner.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# check permission
|
||||
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)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
raise Http404
|
||||
|
||||
# check POST arg
|
||||
repo_owner = request.POST.get('repo_owner', '').lower()
|
||||
if not is_valid_username(repo_owner):
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('Username %s is not valid.') % repo_owner,
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
try:
|
||||
User.objects.get(email=repo_owner)
|
||||
except User.DoesNotExist:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('User %s is not found.') % repo_owner,
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
if not seaserv.ccnet_threaded_rpc.org_user_exists(org_id, repo_owner):
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('User %s is not in current organization.') %
|
||||
repo_owner,}), status=400, content_type=content_type)
|
||||
|
||||
if repo_owner and repo_owner != username:
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
seafile_api.set_org_repo_owner(org_id, repo_id, repo_owner)
|
||||
else:
|
||||
if ccnet_threaded_rpc.get_orgs_by_user(repo_owner):
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('Can not transfer library to organization user %s.') % repo_owner,
|
||||
}), status=400, content_type=content_type)
|
||||
else:
|
||||
seafile_api.set_repo_owner(repo_id, repo_owner)
|
||||
|
||||
messages.success(request,
|
||||
_(u'Library %(repo_name)s has been transfered to %(new_owner)s.') %
|
||||
{'repo_name': repo.name, 'new_owner': repo_owner})
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def ajax_repo_change_passwd(request, repo_id):
|
||||
"""Handle ajax post request to change library password.
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
username = request.user.username
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# check permission
|
||||
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)
|
||||
is_owner = True if username == repo_owner else False
|
||||
if not is_owner:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': _('Faied to change password, you are not owner.')}),
|
||||
status=400, content_type=content_type)
|
||||
|
||||
old_passwd = request.POST.get('old_passwd', '')
|
||||
new_passwd = request.POST.get('new_passwd', '')
|
||||
try:
|
||||
seafile_api.change_repo_passwd(repo_id, old_passwd, new_passwd, username)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({
|
||||
'error': e.msg,
|
||||
}), status=400, content_type=content_type)
|
||||
|
||||
messages.success(request, _(u'Successfully updated the password of Library %(repo_name)s.') %
|
||||
{'repo_name': repo.name})
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def add_user_folder_permission(request, repo_id):
|
||||
"""
|
||||
Add folder permission to a user
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
user = request.POST.get('user', None)
|
||||
path = request.POST.get('path', None)
|
||||
perm = request.POST.get('perm', None)
|
||||
|
||||
if not user or not path or not perm:
|
||||
return HttpResponse(json.dumps({"error": _('Argument missing')}),
|
||||
status=400,
|
||||
content_type=content_type)
|
||||
|
||||
result = check_user_folder_perm_args(request.user, repo_id, path, user, perm)
|
||||
if 'error' in result:
|
||||
return HttpResponse(json.dumps(result), status=result['status'],
|
||||
content_type=content_type)
|
||||
|
||||
try:
|
||||
seafile_api.add_folder_user_perm(repo_id, path, perm, user)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({"error": e.msg}), status=500,
|
||||
content_type=content_type)
|
||||
|
||||
messages.success(request, _(u'Success'))
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def remove_user_folder_permission(request, repo_id):
|
||||
"""
|
||||
Remove folder permission of a user
|
||||
"""
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
user = request.GET.get('user', None)
|
||||
path = request.GET.get('path', None)
|
||||
|
||||
if not user or not path:
|
||||
return HttpResponse(json.dumps({"error": _('Argument missing')}),
|
||||
status=400,
|
||||
content_type=content_type)
|
||||
|
||||
result = check_user_folder_perm_args(request.user, repo_id, path, user)
|
||||
if 'error' in result:
|
||||
return HttpResponse(json.dumps(result), status=result['status'],
|
||||
content_type=content_type)
|
||||
|
||||
try:
|
||||
seafile_api.rm_folder_user_perm(repo_id, path, user)
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({"error": e.msg}), status=500,
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def toggle_user_folder_permission(request, repo_id):
|
||||
"""
|
||||
Change folder permission of a user
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
user = request.POST.get('user', None)
|
||||
path = request.POST.get('path', None)
|
||||
perm = request.POST.get('perm', None)
|
||||
|
||||
print user, path, perm
|
||||
if not user or not path or not perm:
|
||||
return HttpResponse(json.dumps({"error": _('Argument missing')}),
|
||||
status=400,
|
||||
content_type=content_type)
|
||||
|
||||
result = check_user_folder_perm_args(request.user, repo_id, path, user, perm)
|
||||
if 'error' in result:
|
||||
return HttpResponse(json.dumps(result), status=result['status'],
|
||||
content_type=content_type)
|
||||
|
||||
try:
|
||||
seafile_api.set_folder_user_perm(repo_id, path, perm, user)
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({"error": e.msg}), status=500,
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def add_group_folder_permission(request, repo_id):
|
||||
"""
|
||||
Add folder permission to a group
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
group_id = request.POST.get('group_id', None)
|
||||
path = request.POST.get('path', None)
|
||||
perm = request.POST.get('perm', None)
|
||||
|
||||
if not group_id or not path or not perm:
|
||||
return HttpResponse(json.dumps({"error": _('Argument missing')}),
|
||||
status=400,
|
||||
content_type=content_type)
|
||||
group_id = int(group_id)
|
||||
result = check_group_folder_perm_args(request.user, repo_id, path, group_id, perm)
|
||||
if 'error' in result:
|
||||
return HttpResponse(json.dumps(result), status=result['status'],
|
||||
content_type=content_type)
|
||||
|
||||
try:
|
||||
seafile_api.add_folder_group_perm(repo_id, path, perm, group_id)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({"error": e.msg}), status=500,
|
||||
content_type=content_type)
|
||||
|
||||
messages.success(request, _(u'Success'))
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def remove_group_folder_permission(request, repo_id):
|
||||
"""
|
||||
Remove folder permission of a group
|
||||
"""
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
group_id = int(request.GET.get('group_id', None))
|
||||
path = request.GET.get('path', None)
|
||||
|
||||
if not group_id or not path:
|
||||
return HttpResponse(json.dumps({"error": _('Argument missing')}),
|
||||
status=400,
|
||||
content_type=content_type)
|
||||
|
||||
result = check_group_folder_perm_args(request.user, repo_id, path, group_id)
|
||||
if 'error' in result:
|
||||
return HttpResponse(json.dumps(result), status=result['status'],
|
||||
content_type=content_type)
|
||||
|
||||
try:
|
||||
seafile_api.rm_folder_group_perm(repo_id, path, group_id)
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({"error": e.msg}), status=500,
|
||||
content_type=content_type)
|
||||
|
||||
@login_required_ajax
|
||||
def toggle_group_folder_permission(request, repo_id):
|
||||
"""
|
||||
Change folder permission of a group
|
||||
"""
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
|
||||
group_id = int(request.POST.get('group_id', None))
|
||||
path = request.POST.get('path', None)
|
||||
perm = request.POST.get('perm', None)
|
||||
|
||||
if not group_id or not path or not perm:
|
||||
return HttpResponse(json.dumps({"error": _('Argument missing')}),
|
||||
status=400,
|
||||
content_type=content_type)
|
||||
|
||||
result = check_group_folder_perm_args(request.user, repo_id, path, group_id, perm)
|
||||
if 'error' in result:
|
||||
return HttpResponse(json.dumps(result), status=result['status'],
|
||||
content_type=content_type)
|
||||
|
||||
try:
|
||||
seafile_api.set_folder_group_perm(repo_id, path, perm, group_id)
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=content_type)
|
||||
except SearpcError, e:
|
||||
return HttpResponse(json.dumps({"error": e.msg}), status=500,
|
||||
content_type=content_type)
|
||||
|
@ -58,6 +58,7 @@ from seahub.utils.file_types import (IMAGE, PDF, DOCUMENT, SPREADSHEET,
|
||||
MARKDOWN, TEXT, SF, OPENDOCUMENT)
|
||||
from seahub.utils.star import is_file_starred
|
||||
from seahub.utils import HAS_OFFICE_CONVERTER, FILEEXT_TYPE_MAP
|
||||
from seahub.views import check_folder_permission
|
||||
|
||||
if HAS_OFFICE_CONVERTER:
|
||||
from seahub.utils import (
|
||||
@ -957,14 +958,15 @@ def file_edit(request, repo_id):
|
||||
if request.method == 'POST':
|
||||
return file_edit_submit(request, repo_id)
|
||||
|
||||
if check_repo_access_permission(repo_id, request.user) != 'rw':
|
||||
return render_permission_error(request, _(u'Unable to edit file'))
|
||||
|
||||
path = request.GET.get('p', '/')
|
||||
if path[-1] == '/':
|
||||
path = path[:-1]
|
||||
u_filename = os.path.basename(path)
|
||||
filename = urllib2.quote(u_filename.encode('utf-8'))
|
||||
parent_dir = os.path.dirname(path)
|
||||
|
||||
if check_folder_permission(repo.id, parent_dir, request.user.username) != 'rw':
|
||||
return render_permission_error(request, _(u'Unable to edit file'))
|
||||
|
||||
head_id = repo.head_cmmt_id
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user