1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-01 07:10:55 +00:00

[sysadmin-log] Show file-audit/update & permission log

This commit is contained in:
lian 2015-03-25 13:36:24 +08:00
parent 2ee4d9a16c
commit 7b51afe600
24 changed files with 358 additions and 87 deletions

View File

@ -1848,6 +1848,7 @@ textarea:-moz-placeholder {/* for FF */
.displayed-op .op:hover {
text-decoration:none;
}
.audit-item .audit-select-hidden,
.repo-file-list .hidden-op {
position:absolute;
background:#fff;
@ -1856,6 +1857,7 @@ textarea:-moz-placeholder {/* for FF */
border-radius:5px;
z-index:10;
}
.audit-select-hidden li a,
.hidden-op li a {
display:block;
padding:0 12px;
@ -1864,6 +1866,13 @@ textarea:-moz-placeholder {/* for FF */
width:500px;
padding:10px 20px;
}
.perm-dir-tree-cont {
padding:5px;
height:100px;
overflow:auto;
border:1px solid #eee;
margin:5px 0 10px;
}
.file-tree-cont, .dir-tree-cont {
padding:5px;
height:280px;
@ -3347,6 +3356,11 @@ textarea:-moz-placeholder {/* for FF */
}
/* repo setting */
.user-perm-add-tr input,
.group-perm-add-tr input {
padding:2px 5px;
}
.user-perm-add-perm,
.group-perm-add-perm,
.perm-toggle-select,
@ -3368,3 +3382,25 @@ textarea:-moz-placeholder {/* for FF */
#perm-add-jstree-wrap {
background:#fcfcfc;
}
/* file audit*/
.audit-show-select {
font-weight: normal;
font-size: 13px;
padding-right: 2px;
}
#audit-unselect-op div {
display: inline-block;
height: 20px;
border: 1px solid #ccc;
background: #f2f2f2;
cursor: pointer;
}
#audit-unselect-op span {
margin-right: 5px;
}
#audit-unselect-op a {
margin: 0 8px;
text-decoration: none;
font-size: 14px;
}

View File

@ -26,7 +26,6 @@ from django.http import HttpResponse, Http404
from django.template import RequestContext
from django.template.loader import render_to_string
from django.shortcuts import render_to_response
from django.utils import timezone
from .throttling import ScopedRateThrottle
from .authentication import TokenAuthentication
@ -63,6 +62,7 @@ from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \
get_org_user_events
from seahub.utils.star import star_file, unstar_file
from seahub.utils.file_types import IMAGE, DOCUMENT
from seahub.utils.timeutils import utc_to_local
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, check_folder_permission
@ -2549,12 +2549,6 @@ class EventsView(APIView):
else:
d['author'] = e.repo_owner
def utc_to_local(dt):
tz = timezone.get_default_timezone()
utc = dt.replace(tzinfo=timezone.utc)
local = timezone.make_naive(utc, tz)
return local
epoch = datetime.datetime(1970, 1, 1)
local = utc_to_local(e.timestamp)
time_diff = local - epoch

View File

@ -49,7 +49,7 @@
{% endif %}
</td>
<td>{{ repo.owner|email2nickname }}</td>
<td data-id="{{ repo.props.id }}" data-owner="{{ repo.owner }}" data-name="{{ repo.props.name }}">
<td data-id="{{ repo.props.id }}" data-owner="{{ repo.owner }}" data-name="{{ repo.props.name }}" data-perm="{{ repo.user_perm }}">
{% if is_staff or repo.share_from_me %}
<img src="{{MEDIA_URL}}img/rm.png" alt="" class="cancel-share op-icon vh" title="{% trans "Unshare" %}" />
{% endif %}
@ -141,8 +141,9 @@ $('.cancel-share').click(function() {
var btn_ct = $(this).parent(),
repo_id = btn_ct.data('id'),
repo_owner = btn_ct.attr('data-owner'),
repo_perm = btn_ct.attr('data-perm'),
repo_name = btn_ct.attr('data-name');
$(this).data('url', '{% url 'repo_remove_share' %}?repo_id=' + e(repo_id) + '&from=' + e(repo_owner) + '&gid={{ group.id }}').attr('data-target', repo_name);
$(this).data('url', '{% url 'repo_remove_share' %}?repo_id=' + e(repo_id) + '&from=' + e(repo_owner) + '&gid={{ group.id }}' + '&permission=' + e(repo_perm)).attr('data-target', repo_name);
});
addConfirmTo($('.cancel-share'), {
'title': "{% trans "Unshare Library" %}",

View File

@ -427,6 +427,11 @@ PREVIEW_DEFAULT_SIZE = '100'
# for origin image file: size(MB)
THUMBNAIL_IMAGE_SIZE_LIMIT = 30
#####################
# Folder Permission #
#####################
ENABLE_FOLDER_PERM = False
#################
# Email sending #
#################

View File

@ -40,14 +40,14 @@
<td>{{ repo.props.repo_desc }}</td>
<td>
{% if repo.props.share_type == 'group' %}
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&gid={{ repo.props.group_id }}" class="op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&gid={{ repo.props.group_id }}&permission={{ repo.props.permission }}" class="op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% endif %}
{% if repo.props.share_type == 'personal' %}
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&to={{ repo.props.user|urlencode }}" class="op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&to={{ repo.props.user|urlencode }}&permission={{ repo.props.permission }}" class="op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% endif %}
{% if repo.props.share_type == 'public' %}
{% if not org %}
<a href="{% url 'unsetinnerpub' repo.repo_id %}" class="op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
<a href="{% url 'unsetinnerpub' repo.repo_id %}?permission={{ repo.props.permission }}" class="op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% else %}
<a href="{{ SITE_ROOT }}organizations/{{ org.url_prefix }}/innerpubrepo/unset/{{ repo.props.repo_id }}" class="op-icon vh" title="{% trans "Unshare" %}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% endif %}
@ -92,10 +92,8 @@ $('.share-permission-select').change(function() {
success: function(data) {
if (data['success']) {
feedback("{% trans "Edit succeeded" %}", 'success');
select.prev().children('.share-permission-cur-value').html(select.children('option[value="' +select.val() + '"]').text());
location.reload(true);
}
select.addClass('hide');
select.prev().removeClass('hide');
},
error: function() {
feedback("{% trans "Edit failed." %}", 'error');

View File

@ -44,13 +44,13 @@
<td>{{ repo.props.repo_desc }}</td>
<td>
{% if repo.props.share_type == 'group' %}
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&gid={{ repo.props.group_id }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&gid={{ repo.props.group_id }}&permission={{ repo.props.permission }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% endif %}
{% if repo.props.share_type == 'personal' %}
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&to={{ repo.props.user|urlencode }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
<a href="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&to={{ repo.props.user|urlencode }}&permission={{ repo.props.permission }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% endif %}
{% if repo.props.share_type == 'public' %}
<a href="{% url 'unsetinnerpub' repo.repo_id %}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
<a href="{% url 'unsetinnerpub' repo.repo_id %}?permission={{ repo.props.permission }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
{% endif %}
</td>
</tr>

View File

@ -56,9 +56,9 @@
<span data="{{ repo.repo_id }}" class="icon-cloud-download download-btn op-icon vh" title="{% trans "Download and Sync" %}"></span>
{% endif %}
{% if repo.share_in %}
<span data-url="{% url 'repo_remove_share' %}?repo_id={{ repo.repo_id }}&from={{ repo.user|urlencode }}&to={{ request.user.username|urlencode }}" data-target="{{repo.repo_name}}" class="icon-trash unshare-btn op-icon vh" title="{% trans "Leave Share" %}"></span>
<span data-url="{% url 'repo_remove_share' %}?repo_id={{ repo.repo_id }}&from={{ repo.user|urlencode }}&to={{ request.user.username|urlencode }}&permission={{ repo.permission }}" data-target="{{repo.repo_name}}" class="icon-trash unshare-btn op-icon vh" title="{% trans "Leave Share" %}"></span>
{% else %}
<span data-url="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&to={{ repo.props.user|urlencode }}" data-target="{{repo.repo_name}}" class="icon-trash unshare-btn op-icon vh" title="{% trans "Unshare"%}"></span>
<span data-url="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user.username|urlencode }}&to={{ repo.props.user|urlencode }}&permission={{ repo.permission }}" data-target="{{repo.repo_name}}" class="icon-trash unshare-btn op-icon vh" title="{% trans "Unshare"%}"></span>
{% endif %}
</td>
</tr>

View File

@ -40,8 +40,8 @@ from seahub.views import is_registered_user, check_repo_access_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, \
is_valid_username, send_html_email, is_org_context, \
normalize_file_path, normalize_dir_path
is_valid_username, send_html_email, is_org_context, normalize_file_path, \
normalize_dir_path, send_perm_audit_msg, get_origin_repo_info
from seahub.settings import SITE_ROOT, REPLACE_FROM_EMAIL, ADD_REPLY_TO_HEADER
# Get an instance of a logger
@ -253,8 +253,18 @@ def share_repo(request):
if is_valid_username(share_to):
share_to_users.append(share_to)
origin_repo_id, origin_path = get_origin_repo_info(repo.id)
if origin_repo_id is not None:
perm_repo_id = origin_repo_id
perm_path = origin_path
else:
perm_repo_id = repo.id
perm_path = '/'
if share_to_all:
share_to_public(request, repo, permission)
send_perm_audit_msg('add-repo-perm', username, 'all', \
perm_repo_id, perm_path, permission)
if not check_user_share_quota(username, repo, users=share_to_users,
groups=share_to_groups):
@ -266,11 +276,15 @@ def share_repo(request):
for group in share_to_groups:
share_to_group(request, repo, group, permission)
send_perm_audit_msg('add-repo-perm', username, group.id, \
perm_repo_id, perm_path, permission)
for email in share_to_users:
# Add email to contacts.
mail_sended.send(sender=None, user=request.user.username, email=email)
share_to_user(request, repo, email, permission)
send_perm_audit_msg('add-repo-perm', username, email, \
perm_repo_id, perm_path, permission)
return HttpResponseRedirect(next)
@ -285,10 +299,23 @@ def repo_remove_share(request):
repo_id = request.GET.get('repo_id', '')
group_id = request.GET.get('gid', '')
from_email = request.GET.get('from', '')
if not is_valid_username(from_email):
perm = request.GET.get('permission', None)
if not is_valid_username(from_email) or perm is None:
return render_error(request, _(u'Argument is not valid'))
username = request.user.username
repo = seafile_api.get_repo(repo_id)
if not repo:
return render_error(request, _(u'Library does not exist'))
origin_repo_id, origin_path = get_origin_repo_info(repo.id)
if origin_repo_id is not None:
perm_repo_id = origin_repo_id
perm_path = origin_path
else:
perm_repo_id = repo.id
perm_path = '/'
# if request params don't have 'gid', then remove repos that share to
# to other person; else, remove repos that share to groups
if not group_id:
@ -304,6 +331,8 @@ def repo_remove_share(request):
org_remove_share(org_id, repo_id, from_email, to_email)
else:
seaserv.remove_share(repo_id, from_email, to_email)
send_perm_audit_msg('delete-repo-perm', from_email, to_email, \
perm_repo_id, perm_path, perm)
else:
try:
group_id = int(group_id)
@ -323,6 +352,8 @@ def repo_remove_share(request):
del_org_group_repo(repo_id, org_id, group_id)
else:
seafile_api.unset_group_repo(repo_id, group_id, from_email)
send_perm_audit_msg('delete-repo-perm', from_email, group_id, \
perm_repo_id, perm_path, perm)
messages.success(request, _('Successfully removed share'))
@ -566,6 +597,19 @@ def share_permission_admin(request):
permission = form.cleaned_data['permission']
from_email = request.user.username
repo = seafile_api.get_repo(repo_id)
if not repo:
return render_error(request, _(u'Library does not exist'))
origin_repo_id, origin_path = get_origin_repo_info(repo.id)
if origin_repo_id is not None:
perm_repo_id = origin_repo_id
perm_path = origin_path
else:
perm_repo_id = repo.id
perm_path = '/'
if share_type == 'personal':
if not is_valid_username(email_or_group):
return HttpResponse(json.dumps({'success': False}), status=400,
@ -579,6 +623,9 @@ def share_permission_admin(request):
else:
seafile_api.set_share_permission(repo_id, from_email,
email_or_group, permission)
send_perm_audit_msg('modify-repo-perm', from_email, \
email_or_group, perm_repo_id, perm_path, permission)
except SearpcError:
return HttpResponse(json.dumps({'success': False}), status=500,
content_type=content_type)
@ -592,8 +639,12 @@ def share_permission_admin(request):
seaserv.seafserv_threaded_rpc.set_org_group_repo_permission(
org_id, int(email_or_group), repo_id, permission)
else:
seafile_api.set_group_repo_permission(int(email_or_group),
repo_id, permission)
group_id = int(email_or_group)
seafile_api.set_group_repo_permission(group_id,
repo_id,
permission)
send_perm_audit_msg('modify-repo-perm', from_email, \
group_id, perm_repo_id, perm_path, permission)
except SearpcError:
return HttpResponse(json.dumps({'success': False}), status=500,
content_type=content_type)
@ -608,6 +659,8 @@ def share_permission_admin(request):
org_id, repo_id, permission)
else:
seafile_api.add_inner_pub_repo(repo_id, permission)
send_perm_audit_msg('modify-repo-perm', from_email, 'all', \
perm_repo_id, perm_path, permission)
except SearpcError:
return HttpResponse(json.dumps({'success': False}), status=500,
content_type=content_type)

View File

@ -38,7 +38,7 @@
<td>{{ repo.props.user|email2nickname }}</td>
<td>
{% if request.user.is_staff or repo.share_from_me %}
<img src="{{MEDIA_URL}}img/rm.png" alt="" data-href="{% url 'unsetinnerpub' repo.repo_id %}" class="cancel-share op-icon vh" title="{% trans "Unshare" %}" />
<img src="{{MEDIA_URL}}img/rm.png" alt="" data-href="{% url 'unsetinnerpub' repo.repo_id %}?permission={{repo.permission}}" class="cancel-share op-icon vh" title="{% trans "Unshare" %}" />
{% endif %}
</td>
</tr>

View File

@ -23,8 +23,10 @@
{% 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>
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Permission" %}</a></li>
{% if ENABLE_FOLDER_PERM %}
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "Folder Permission" %}</a></li>
{% endif %}
</ul>
</div>
{% endblock %}

View File

@ -23,8 +23,10 @@
{% 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>
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Permission" %}</a></li>
{% if ENABLE_FOLDER_PERM %}
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "Folder Permission" %}</a></li>
{% endif %}
</ul>
</div>
{% endblock %}

View File

@ -23,8 +23,8 @@
{% 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>
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Permission" %}</a></li>
<li class="tab tab-cur"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "Folder Permission" %}</a></li>
</ul>
</div>
{% endblock %}
@ -33,7 +33,7 @@
<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>
<p>{% trans "View and manage all folder permissions in this library." %}</p>
<div id="tabs" class="tab-tabs">
<div class="hd ovhd">
<ul class="tab-tabs-nav fleft">
@ -54,9 +54,9 @@
<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 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-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>
@ -71,7 +71,7 @@
</tr>
{% if user_folder_perms %}
{% for perm in user_folder_perms %}
<tr class="perm-item" data-user="{{ perm.user }}" data-path="{{ perm.path }}">
<tr class="perm-item" data-user="{{ perm.user }}" data-path="{{ perm.path }}" data-perm="{{ perm.permission }}">
<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>
@ -107,11 +107,11 @@
</tr>
<tr class="group-perm-add-tr hide">
<td>
<input id="perm-add-grp-name" placeholder=" {% trans "Group"%}"></input>
<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-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>
@ -126,7 +126,7 @@
</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 }}">
<tr class="perm-item" data-group_id="{{ perm.group_id }}" data-path="{{ perm.path }}" data-perm="{{ perm.permission }}">
<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>
@ -157,7 +157,7 @@
<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>
<div id="perm-add-jstree" class="perm-dir-tree-cont" 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>
@ -197,7 +197,7 @@ group_list.push({value:group_id, label:group_name});
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()});
widget.css({'max-width':user_input.width() + 2 * parseInt(widget.css('padding-top')), 'max-height':$(window).height() + $(window).scrollTop() - user_input.offset().top - user_input.outerHeight()});
})
.autocomplete({
source: user_list
@ -205,7 +205,7 @@ user_input.bind('autocompleteopen', function(e, ui) {
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()});
widget.css({'max-width':group_input.width() + 2 * parseInt(widget.css('padding-top')), 'max-height':$(window).height() + $(window).scrollTop() - group_input.offset().top - group_input.outerHeight()});
})
.autocomplete({
source: group_list,
@ -250,15 +250,16 @@ $('.perm-toggle-select').on('change', function() {
});
$('.perm-delete-btn').on('click', function() {
var perm_item = $(this).parents('.perm-item'),
perm = perm_item.attr('data-perm'),
path = perm_item.attr('data-path');
if (is_user_tab == true) {
var user = perm_item.attr('data-user'),
data = { 'user': user, 'path': path },
data = { 'user': user, 'path': path, 'perm': perm },
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 },
data = { 'group_id': group_id, 'path': path, 'perm': perm},
url = '{% url 'remove_group_folder_permission' repo.id %}';
}
@ -329,7 +330,7 @@ function selectClickHandler(event) {
}
if (path_array.length == 1) {
path = path_array.shift();
folder_name.val('Root Directory');
folder_name.val('/');
} else {
var root = path_array.shift(),
path = root + path_array.join('/'),

View File

@ -23,8 +23,10 @@
{% 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>
<li class="tab tab-cur"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Permission" %}</a></li>
{% if ENABLE_FOLDER_PERM %}
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "Folder Permission" %}</a></li>
{% endif %}
</ul>
</div>
{% endblock %}
@ -33,7 +35,7 @@
<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>
<p>{% trans "View and manage sharing permissions of this library." %}</p>
<div id="tabs" class="tab-tabs">
<div class="hd ovhd">
@ -72,7 +74,7 @@
</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>
<a href="{% url 'repo_remove_share' %}?repo_id={{ share.repo_id }}&from={{ request.user.username|urlencode }}&to={{ share.user|urlencode }}&permission={{ share.permission }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
</td>
</tr>
{% endfor %}
@ -105,7 +107,7 @@
</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>
<a href="{% url 'repo_remove_share' %}?repo_id={{ share.repo_id }}&from={{ request.user.username|urlencode }}&gid={{ share.group_id }}&permission={{ share.permission }}" class="cancel-share op-icon vh" title="{% trans "Unshare"%}"><img src="{{MEDIA_URL}}img/rm.png" alt="" /></a>
</td>
</tr>
{% endfor %}

View File

@ -23,8 +23,10 @@
{% 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>
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Permission" %}</a></li>
{% if ENABLE_FOLDER_PERM %}
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "Folder Permission" %}</a></li>
{% endif %}
</ul>
</div>
{% endblock %}

View File

@ -23,8 +23,10 @@
{% 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>
<li class="tab"><a href="{% url 'repo_share_manage' repo.id %}">{% trans "Sharing Permission" %}</a></li>
{% if ENABLE_FOLDER_PERM %}
<li class="tab"><a href="{% url 'repo_folder_perm' repo.id %}">{% trans "Folder Permission" %}</a></li>
{% endif %}
</ul>
</div>
{% endblock %}

View File

@ -33,7 +33,7 @@
{% endif %}
{% endif %}
{% if not traffic_over_limit %}
<a href="{{ SITE_ROOT }}repo/{{ repo.id }}/{{ obj_id }}/?file_name={{ file_name|urlencode }}&op=download&t={{ shared_token }}&p={{path|urlencode}}" class="obv-btn">{% trans "Download" %} ({{file_size|filesizeformat}})</a>
<a href="{% url 'download_file' repo.id obj_id%}?file_name={{ file_name|urlencode }}&t={{ shared_token }}&p={{path|urlencode}}" class="obv-btn">{% trans "Download" %} ({{file_size|filesizeformat}})</a>
{% endif %}
</div>
{% include 'snippets/file_content_html.html' %}

View File

@ -26,7 +26,7 @@
<span data="{{ repo.repo_id }}" class="icon-cloud-download download-btn op-icon vh" title="{% trans "Download and Sync" %}"></span>
{% endif %}
{% if repo.share_type == 'personal' %}
<span data-url="{% url 'repo_remove_share' %}?repo_id={{ repo.repo_id }}&from={{ repo.user|urlencode }}&to={{ request.user.username|urlencode }}" data-target="{{repo.repo_name}}" class="icon-trash unshare-btn op-icon vh" title="{% trans "Leave Share" %}"></span>
<span data-url="{% url 'repo_remove_share' %}?repo_id={{ repo.repo_id }}&from={{ repo.user|urlencode }}&to={{ request.user.username|urlencode }}&permission={{ repo.user_perm }}" data-target="{{repo.repo_name}}" class="icon-trash unshare-btn op-icon vh" title="{% trans "Leave Share" %}"></span>
{% endif %}
</td>
</tr>

View File

@ -254,9 +254,13 @@ if getattr(settings, 'ENABLE_PAYMENT', False):
if getattr(settings, 'ENABLE_SYSADMIN_EXTRA', False):
from seahub_extra.sysadmin_extra.views import sys_login_admin
from seahub_extra.sysadmin_extra.views import sys_login_admin, \
sys_log_file_audit, sys_log_file_update, sys_log_perm_audit
urlpatterns += patterns('',
url(r'^sys/loginadmin/', sys_login_admin, name='sys_login_admin'),
url(r'^sys/log/fileaudit/', sys_log_file_audit, name='sys_log_file_audit'),
url(r'^sys/log/fileupdate/', sys_log_file_update, name='sys_log_file_update'),
url(r'^sys/log/permaudit/', sys_log_perm_audit, name='sys_log_perm_audit'),
)
if getattr(settings, 'MULTI_TENANCY', False):

View File

@ -10,6 +10,7 @@ import tempfile
import locale
import ConfigParser
import mimetypes
import contextlib
from datetime import datetime
from urlparse import urlparse, urljoin
@ -31,8 +32,8 @@ from django.views.static import serve as django_static_serve
from seahub.api2.models import Token, TokenV2
import seaserv
from seaserv import seafile_api
from seaserv import seafserv_rpc, seafserv_threaded_rpc, get_repo, get_commits,\
from seaserv import seafile_api, send_message, seafserv_rpc, \
seafserv_threaded_rpc, get_repo, get_commits,\
CCNET_SERVER_ADDR, CCNET_SERVER_PORT, get_org_by_id, is_org_staff, \
get_org_id_by_group, get_personal_groups_by_user, \
list_personal_repos_by_owner, get_group_repos, \
@ -526,6 +527,14 @@ if EVENTS_CONFIG_FILE:
EVENTS_ENABLED = True
SeafEventsSession = seafevents.init_db_session_class(EVENTS_CONFIG_FILE)
@contextlib.contextmanager
def _get_seafevents_session():
try:
session = SeafEventsSession()
yield session
finally:
session.close()
def _same_events(e1, e2):
"""Two events are equal should follow two rules:
1. event1.repo_id = event2.repo_id
@ -634,6 +643,48 @@ if EVENTS_CONFIG_FILE:
def get_org_user_events(org_id, username, start, count):
return _get_events(username, start, count, org_id=org_id)
def get_file_audit_events(email, org_id, repo_id, start, limit):
"""Return file audit events list. (If no file audit, return 'None')
For example:
``get_file_audit_events(email, org_id, repo_id, 0, 10)`` returns the first 10
events.
``get_file_audit_events(email, org_id, repo_id, 5, 10)`` returns the 6th through
15th events.
"""
with _get_seafevents_session() as session:
events = seafevents.get_file_audit_events(session, email, org_id, repo_id, start, limit)
return events if events else None
def get_file_update_events(email, org_id, repo_id, start, limit):
"""Return file update events list. (If no file update, return 'None')
For example:
``get_file_update_events(email, org_id, repo_id, 0, 10)`` returns the first 10
events.
``get_file_update_events(email, org_id, repo_id, 5, 10)`` returns the 6th through
15th events.
"""
with _get_seafevents_session() as session:
events = seafevents.get_file_update_events(session, email, org_id, repo_id, start, limit)
return events if events else None
def get_perm_audit_events(email, org_id, repo_id, start, limit):
"""Return repo perm events list. (If no repo perm, return 'None')
For example:
``get_repo_perm_events(email, org_id, repo_id, 0, 10)`` returns the first 10
events.
``get_repo_perm_events(email, org_id, repo_id, 5, 10)`` returns the 6th through
15th events.
"""
with _get_seafevents_session() as session:
events = seafevents.get_perm_audit_events(session, email, org_id, repo_id, start, limit)
return events if events else None
else:
EVENTS_ENABLED = False
def get_user_events():
@ -1192,3 +1243,31 @@ def clear_token(username):
Token.objects.filter(user = username).delete()
TokenV2.objects.filter(user = username).delete()
seafile_api.delete_repo_tokens_by_email(username)
def send_perm_audit_msg(etype, from_user, to, repo_id, path, perm):
"""Send repo permission audit msg.
Arguments:
- `request`:
- `repo`:
- `obj_id`:
- `dl_type`: web or api
"""
msg = 'perm-update\t%s\t%s\t%s\t%s\t%s\t%s' % \
(etype, from_user, to, repo_id, path, perm)
msg_utf8 = msg.encode('utf-8')
try:
send_message('seahub.stats', msg_utf8)
except Exception as e:
logger.error("Error when sending perm-audit-%s message: %s" %
(etype, str(e)))
def get_origin_repo_info(repo_id):
repo = seafile_api.get_repo(repo_id)
if repo.origin_repo_id is not None:
origin_repo_id = repo.origin_repo_id
origin_path = repo.origin_path
return (origin_repo_id, origin_path)
return (None, None)

View File

@ -1,11 +1,15 @@
# -*- coding: utf-8 -*-
import logging
from django.utils.translation import ugettext as _
import seaserv
from seaserv import seafile_api
from seahub.utils import EMPTY_SHA1, is_valid_username
from seahub.utils import EMPTY_SHA1
from seahub.views import check_repo_access_permission
from seahub.base.accounts import User
logger = logging.getLogger(__name__)
def list_dir_by_path(cmmt, path):
if cmmt.root_id == EMPTY_SHA1:
@ -13,11 +17,11 @@ def list_dir_by_path(cmmt, path):
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):
def check_user_folder_perm_args(from_user, repo_id, path, to_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':
if check_repo_access_permission(repo_id, from_user) != 'rw':
return {'error': _('Permission denied'), 'status': 403}
if perm is not None:
@ -34,16 +38,21 @@ def check_user_folder_perm_args(request_user, repo_id, path, user, perm=None):
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}
try:
user = User.objects.get(email = to_user)
except User.DoesNotExist:
user = None
if user is None:
return {'error': _('Invalid username, should be a user already registered'), 'status': 400}
return {'success': True}
def check_group_folder_perm_args(request_user, repo_id, path, group_id, perm = None):
def check_group_folder_perm_args(from_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':
if check_repo_access_permission(repo_id, from_user) != 'rw':
return {'error': _('Permission denied'), 'status': 403}
if perm is not None:
@ -60,7 +69,8 @@ def check_group_folder_perm_args(request_user, repo_id, path, group_id, perm = N
if path != '/' and path.endswith('/'):
return {'error': _('Path should NOT ends with "/"'), 'status': 400}
if group_id and not seaserv.get_group(group_id):
if not seaserv.get_group(group_id):
return {'error': _('Invalid group'), 'status': 400}
return {'success': True}

View File

@ -26,4 +26,10 @@ def value_to_db_datetime(value):
# MySQL doesn't support microseconds
return six.text_type(value.replace(microsecond=0))
def utc_to_local(dt):
# change from UTC timezone to current seahub timezone
tz = timezone.get_default_timezone()
utc = dt.replace(tzinfo=timezone.utc)
local = timezone.make_naive(utc, tz)
return local

View File

@ -53,9 +53,10 @@ from seahub.utils import render_permission_error, render_error, list_to_string,
gen_file_get_url, string2list, MAX_INT, IS_EMAIL_CONFIGURED, \
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
user_traffic_over_limit, send_perm_audit_msg, get_origin_repo_info
from seahub.utils.paginator import get_page_range
from seahub.utils.star import get_dir_starred_files
from seahub.utils.timeutils import utc_to_local
from seahub.views.modules import MOD_PERSONAL_WIKI, enable_mod_for_user, \
disable_mod_for_user
from seahub.utils.devices import get_user_devices, do_unlink_device
@ -63,7 +64,8 @@ import seahub.settings as settings
from seahub.settings import FILE_PREVIEW_MAX_SIZE, INIT_PASSWD, USE_PDFJS, \
FILE_ENCODING_LIST, FILE_ENCODING_TRY_LIST, AVATAR_FILE_STORAGE, \
SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD, \
ENABLE_SUB_LIBRARY, ENABLE_REPO_HISTORY_SETTING, REPO_PASSWORD_MIN_LENGTH
ENABLE_SUB_LIBRARY, ENABLE_REPO_HISTORY_SETTING, \
REPO_PASSWORD_MIN_LENGTH, ENABLE_FOLDER_PERM
# Get an instance of a logger
logger = logging.getLogger(__name__)
@ -477,6 +479,7 @@ def repo_basic_info(request, repo_id):
'no_history_enabled': no_history_enabled,
'partial_history_enabled': partial_history_enabled,
'days_enabled': days_enabled,
'ENABLE_FOLDER_PERM': ENABLE_FOLDER_PERM,
}, context_instance=RequestContext(request))
@login_required
@ -491,6 +494,7 @@ def repo_transfer_owner(request, repo_id):
return render_to_response('repo_transfer_owner.html', {
'repo': repo,
'ENABLE_FOLDER_PERM': ENABLE_FOLDER_PERM,
}, context_instance=RequestContext(request))
@login_required
@ -506,6 +510,7 @@ def repo_change_password(request, repo_id):
return render_to_response('repo_change_password.html', {
'repo': repo,
'repo_password_min_length': REPO_PASSWORD_MIN_LENGTH,
'ENABLE_FOLDER_PERM': ENABLE_FOLDER_PERM,
}, context_instance=RequestContext(request))
@login_required
@ -565,6 +570,7 @@ def repo_shared_link(request, repo_id):
'repo': repo,
'fileshares': p_fileshares,
'uploadlinks': p_uploadlinks,
'ENABLE_FOLDER_PERM': ENABLE_FOLDER_PERM,
}, context_instance=RequestContext(request))
@login_required
@ -598,6 +604,7 @@ def repo_share_manage(request, repo_id):
'repo': repo,
'repo_share_user': repo_share_user,
'repo_share_group': repo_share_group,
'ENABLE_FOLDER_PERM': ENABLE_FOLDER_PERM,
}, context_instance=RequestContext(request))
@login_required
@ -607,11 +614,42 @@ def repo_folder_perm(request, repo_id):
username = request.user.username
can_access, repo = can_access_repo_setting(request, repo_id, username)
if not can_access:
if not can_access or not ENABLE_FOLDER_PERM:
raise Http404
def not_need_delete(perm):
repo_id = perm.repo_id
path = perm.path
group_id = perm.group_id if hasattr(perm, 'group_id') else None
email = perm.user if hasattr(perm, 'user') else None
repo = get_repo(repo_id)
dir_id = seafile_api.get_dir_id_by_path(repo_id, path)
if group_id is not None:
# is a group folder perm
group = get_group(group_id)
if repo is None or dir_id is None or group is None:
seafile_api.rm_folder_group_perm(repo_id, path, group_id)
return False
if email is not None:
# is a user folder perm
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
user = None
if repo is None or dir_id is None or user is None:
seafile_api.rm_folder_user_perm(repo_id, path, email)
return False
return True
# for user folder permission
user_folder_perms = seafile_api.list_folder_user_perm_by_repo(repo_id)
user_folder_perms = filter(lambda x: not_need_delete(x), user_folder_perms)
user_folder_perms.reverse()
for folder_perm in user_folder_perms:
@ -624,6 +662,8 @@ def repo_folder_perm(request, repo_id):
# for group folder permission
group_folder_perms = seafile_api.list_folder_group_perm_by_repo(repo_id)
group_folder_perms = filter(lambda x: not_need_delete(x), group_folder_perms)
group_folder_perms.reverse()
for folder_perm in group_folder_perms:
@ -633,15 +673,26 @@ def repo_folder_perm(request, repo_id):
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 that already registered
sys_contacts = []
contacts = Contact.objects.get_contacts_by_user(username)
for contact in contacts:
try:
user = User.objects.get(email = contact.contact_email)
except User.DoesNotExist:
user = None
if user is not None:
sys_contacts.append(contact.contact_email)
return render_to_response('repo_folder_perm.html', {
'repo': repo,
'user_folder_perms': user_folder_perms,
'group_folder_perms': group_folder_perms,
'contacts': contacts,
'contacts': sys_contacts,
}, context_instance=RequestContext(request))
def upload_error_msg (code):
@ -1098,6 +1149,9 @@ def unsetinnerpub(request, repo_id):
Only system admin, organization admin or repo owner can perform this op.
"""
repo = get_repo(repo_id)
perm = request.GET.get('permission', None)
if perm is None:
return render_error(request, _(u'Argument is not valid'))
if not repo:
messages.error(request, _('Failed to unshare the library, as it does not exist.'))
return HttpResponseRedirect(reverse('share_admin'))
@ -1124,6 +1178,17 @@ def unsetinnerpub(request, repo_id):
else:
seaserv.unset_inner_pub_repo(repo.id)
origin_repo_id, origin_path = get_origin_repo_info(repo.id)
if origin_repo_id is not None:
perm_repo_id = origin_repo_id
perm_path = origin_path
else:
perm_repo_id = repo.id
perm_path = '/'
send_perm_audit_msg('delete-repo-perm', username, 'all', \
perm_repo_id, perm_path, perm)
messages.success(request, _('Unshare "%s" successfully.') % repo.name)
except SearpcError:
messages.error(request, _('Failed to unshare "%s".') % repo.name)
@ -1793,14 +1858,6 @@ def group_events_data(events):
"""
Group events according to the date.
"""
# e.timestamp is a datetime.datetime in UTC
# change from UTC timezone to current seahub timezone
def utc_to_local(dt):
tz = timezone.get_default_timezone()
utc = dt.replace(tzinfo=timezone.utc)
local = timezone.make_naive(utc, tz)
return local
event_groups = []
for e in events:
e.time = utc_to_local(e.timestamp)

View File

@ -45,7 +45,7 @@ from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
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, \
is_valid_username
is_valid_username, send_perm_audit_msg
from seahub.utils.repo import check_group_folder_perm_args, \
check_user_folder_perm_args
from seahub.utils.star import star_file, unstar_file
@ -1715,7 +1715,10 @@ def repo_history_changes(request, repo_id):
# perm check
if check_repo_access_permission(repo.id, request.user) is None:
return HttpResponse(json.dumps(changes), content_type=content_type)
if request.user.is_staff is True:
pass # Allow system staff to check repo changes
else:
return HttpResponse(json.dumps(changes), content_type=content_type)
username = request.user.username
try:
@ -2109,6 +2112,8 @@ def add_user_folder_permission(request, repo_id):
try:
seafile_api.add_folder_user_perm(repo_id, path, perm, user)
send_perm_audit_msg('add-repo-perm', request.user.username, user, \
repo_id, path, perm)
except SearpcError, e:
return HttpResponse(json.dumps({"error": e.msg}), status=500,
content_type=content_type)
@ -2127,8 +2132,9 @@ def remove_user_folder_permission(request, repo_id):
user = request.GET.get('user', None)
path = request.GET.get('path', None)
perm = request.GET.get('perm', None)
if not user or not path:
if not user or not path or not perm:
return HttpResponse(json.dumps({"error": _('Argument missing')}),
status=400,
content_type=content_type)
@ -2140,6 +2146,8 @@ def remove_user_folder_permission(request, repo_id):
try:
seafile_api.rm_folder_user_perm(repo_id, path, user)
send_perm_audit_msg('delete-repo-perm', request.user.username, user, \
repo_id, path, perm)
return HttpResponse(json.dumps({'success': True}),
content_type=content_type)
except SearpcError, e:
@ -2161,7 +2169,6 @@ def toggle_user_folder_permission(request, repo_id):
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,
@ -2174,6 +2181,8 @@ def toggle_user_folder_permission(request, repo_id):
try:
seafile_api.set_folder_user_perm(repo_id, path, perm, user)
send_perm_audit_msg('modify-repo-perm', request.user.username, user, \
repo_id, path, perm)
return HttpResponse(json.dumps({'success': True}),
content_type=content_type)
except SearpcError, e:
@ -2207,6 +2216,8 @@ def add_group_folder_permission(request, repo_id):
try:
seafile_api.add_folder_group_perm(repo_id, path, perm, group_id)
send_perm_audit_msg('add-repo-perm', request.user.username, \
group_id, repo_id, path, perm)
except SearpcError, e:
return HttpResponse(json.dumps({"error": e.msg}), status=500,
content_type=content_type)
@ -2225,8 +2236,9 @@ def remove_group_folder_permission(request, repo_id):
group_id = int(request.GET.get('group_id', None))
path = request.GET.get('path', None)
perm = request.GET.get('perm', None)
if not group_id or not path:
if not group_id or not path or not perm:
return HttpResponse(json.dumps({"error": _('Argument missing')}),
status=400,
content_type=content_type)
@ -2238,6 +2250,8 @@ def remove_group_folder_permission(request, repo_id):
try:
seafile_api.rm_folder_group_perm(repo_id, path, group_id)
send_perm_audit_msg('delete-repo-perm', request.user.username, \
group_id, repo_id, path, perm)
return HttpResponse(json.dumps({'success': True}),
content_type=content_type)
except SearpcError, e:
@ -2271,6 +2285,8 @@ def toggle_group_folder_permission(request, repo_id):
try:
seafile_api.set_folder_group_perm(repo_id, path, perm, group_id)
send_perm_audit_msg('modify-repo-perm', request.user.username, \
group_id, repo_id, path, perm)
return HttpResponse(json.dumps({'success': True}),
content_type=content_type)
except SearpcError, e:

View File

@ -1079,8 +1079,8 @@ def send_file_download_msg(request, repo, path, dl_type):
ip = get_remote_ip(request)
user_agent = request.META.get("HTTP_USER_AGENT")
msg = 'file-download-%s\t%s\t%s\t%s\t%s\t%s\t%s' % \
(dl_type, username, ip, user_agent, repo.id, repo.name, path)
msg = 'file-download-%s\t%s\t%s\t%s\t%s\t%s' % \
(dl_type, username, ip, user_agent, repo.id, path)
msg_utf8 = msg.encode('utf-8')
try:
@ -1137,6 +1137,7 @@ def download_file(request, repo_id, obj_id):
# send stats message
if from_shared_link:
send_file_download_msg(request, repo, path, 'share-link')
try:
file_size = seafile_api.get_file_size(repo.store_id, repo.version,
obj_id)