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:
parent
2ee4d9a16c
commit
7b51afe600
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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" %}",
|
||||
|
@ -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 #
|
||||
#################
|
||||
|
@ -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');
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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('/'),
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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' %}
|
||||
|
@ -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>
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user