mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-20 10:58:33 +00:00
Added private share
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import datetime
|
||||
from django.db import models
|
||||
|
||||
from seahub.utils import normalize_file_path, normalize_dir_path
|
||||
|
||||
class AnonymousShare(models.Model):
|
||||
"""
|
||||
Model used for sharing repo to unregistered email.
|
||||
@@ -21,3 +23,81 @@ class FileShare(models.Model):
|
||||
ctime = models.DateTimeField(default=datetime.datetime.now)
|
||||
view_cnt = models.IntegerField(default=0)
|
||||
s_type = models.CharField(max_length=2, db_index=True, default='f') # `f` or `d`
|
||||
|
||||
|
||||
class PrivateFileDirShareManager(models.Manager):
|
||||
def add_private_file_share(self, from_user, to_user, repo_id, path, perm):
|
||||
"""
|
||||
"""
|
||||
path = normalize_file_path(path)
|
||||
|
||||
pfs = self.model(from_user=from_user, to_user=to_user, repo_id=repo_id,
|
||||
path=path, s_type='f', permission=perm)
|
||||
pfs.save(using=self._db)
|
||||
return pfs
|
||||
|
||||
def get_private_share_in_file(self, username, repo_id, path):
|
||||
"""Get a file that private shared to ``username``.
|
||||
"""
|
||||
path = normalize_file_path(path)
|
||||
|
||||
ret = super(PrivateFileDirShareManager, self).filter(
|
||||
to_user=username, repo_id=repo_id, path=path, s_type='f')
|
||||
return ret[0] if len(ret) > 0 else None
|
||||
|
||||
def add_private_dir_share(self, from_user, to_user, repo_id, path, perm):
|
||||
"""
|
||||
"""
|
||||
path = normalize_dir_path(path)
|
||||
|
||||
pfs = self.model(from_user=from_user, to_user=to_user, repo_id=repo_id,
|
||||
path=path, s_type='d', permission=perm)
|
||||
pfs.save(using=self._db)
|
||||
return pfs
|
||||
|
||||
def get_private_share_in_dir(self, username, repo_id, path):
|
||||
"""Get a directory that private shared to ``username``.
|
||||
"""
|
||||
path = normalize_dir_path(path)
|
||||
|
||||
ret = super(PrivateFileDirShareManager, self).filter(
|
||||
to_user=username, repo_id=repo_id, path=path, s_type='d')
|
||||
return ret[0] if len(ret) > 0 else None
|
||||
|
||||
def delete_private_file_dir_share(self, from_user, to_user, repo_id, path):
|
||||
"""
|
||||
"""
|
||||
super(PrivateFileDirShareManager, self).filter(
|
||||
from_user=from_user, to_user=to_user, repo_id=repo_id,
|
||||
path=path).delete()
|
||||
|
||||
def list_private_share_out_by_user(self, from_user):
|
||||
"""List files/directories private shared from ``from_user``.
|
||||
"""
|
||||
return super(PrivateFileDirShareManager, self).filter(
|
||||
from_user=from_user)
|
||||
|
||||
def list_private_share_in_by_user(self, to_user):
|
||||
"""List files/directories private shared to ``to_user``.
|
||||
"""
|
||||
return super(PrivateFileDirShareManager, self).filter(
|
||||
to_user=to_user)
|
||||
|
||||
def list_private_share_in_dirs_by_user_and_repo(self, to_user, repo_id):
|
||||
"""List directories private shared to ``to_user`` base on ``repo_id``.
|
||||
"""
|
||||
return super(PrivateFileDirShareManager, self).filter(
|
||||
to_user=to_user, repo_id=repo_id)
|
||||
|
||||
|
||||
class PrivateFileDirShare(models.Model):
|
||||
from_user = models.CharField(max_length=255, db_index=True)
|
||||
to_user = models.CharField(max_length=255, db_index=True)
|
||||
repo_id = models.CharField(max_length=36, db_index=True)
|
||||
path = models.TextField()
|
||||
permission = models.CharField(max_length=2) # `r` or `rw`
|
||||
s_type = models.CharField(max_length=2, default='f') # `f` or `d`
|
||||
objects = PrivateFileDirShareManager()
|
||||
|
||||
|
||||
|
||||
|
@@ -109,6 +109,41 @@
|
||||
<p>{% trans "You can share a folder or a file when you view a library, or share a file when you view it." %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h3>{% trans "Private shares" %}</h3>
|
||||
{% if priv_shares %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="45%">{% trans "File or Folder"%}</th>
|
||||
<th width="25%">{% trans "Library"%}</th>
|
||||
<th width="15%">{% trans "User"%}</th>
|
||||
<th width="15%">{% trans "Operations"%}</th>
|
||||
</tr>
|
||||
{% for e in priv_shares %}
|
||||
<tr>
|
||||
{% if e.s_type == 'f' %}
|
||||
<td><a href="{% url 'repo_view_file' e.repo_id %}?p={{ e.path|urlencode}}">{{e.file_or_dir}}</a></td>
|
||||
{% else %}
|
||||
<td><a href="{% url 'repo' e.repo_id %}?p={{ e.path|urlencode}}">{{e.file_or_dir}}</a></td>
|
||||
{% endif %}
|
||||
<td><a href="{% url 'repo' e.repo_id %}">{{e.repo.name}}</a></td>
|
||||
{% if e.out_or_in == 'out' %}
|
||||
<td>{{e.to_user|email2nickname}}</td>
|
||||
{% else %}
|
||||
<td>{{e.from_user|email2nickname}}</td>
|
||||
{% endif %}
|
||||
<td><a href="{% url 'rm_private_file_share' e.repo_id %}?from={{e.from_user|urlencode}}&to={{e.to_user|urlencode}}&p={{e.path|urlencode}}" class="op">Unshare</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else%}
|
||||
<div class="empty-tips">
|
||||
<h2 class="center-contents">{% trans "You don't have any private shared files/folders" %}</h2>
|
||||
<p>{% trans "You can share a single folder or file to a registered user if you don't want to share hole library to he/she." %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
|
@@ -24,7 +24,7 @@ from seaserv import seafserv_threaded_rpc, get_repo, ccnet_rpc, \
|
||||
list_inner_pub_repos_by_owner, remove_share
|
||||
|
||||
from forms import RepoShareForm, FileLinkShareForm
|
||||
from models import AnonymousShare
|
||||
from models import AnonymousShare, FileShare, PrivateFileDirShare
|
||||
from signals import share_repo_to_user_successful
|
||||
from settings import ANONYMOUS_SHARE_COOKIE_TIMEOUT
|
||||
from tokens import anon_share_token_generator
|
||||
@@ -32,7 +32,6 @@ from seahub.auth.decorators import login_required
|
||||
from seahub.base.accounts import User
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.contacts.signals import mail_sended
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.views import validate_owner, is_registered_user
|
||||
from seahub.utils import render_permission_error, string2list, render_error, \
|
||||
gen_token, gen_shared_link, gen_dir_share_link, gen_file_share_link, \
|
||||
@@ -325,11 +324,26 @@ def share_admin(request):
|
||||
fs.repo = r
|
||||
p_fileshares.append(fs)
|
||||
|
||||
# Private share out/in files/directories
|
||||
priv_share_out = PrivateFileDirShare.objects.list_private_share_out_by_user(username)
|
||||
for e in priv_share_out:
|
||||
e.file_or_dir = os.path.basename(e.path.rstrip('/'))
|
||||
e.out_or_in = 'out'
|
||||
e.repo = seafile_api.get_repo(e.repo_id)
|
||||
|
||||
priv_share_in = PrivateFileDirShare.objects.list_private_share_in_by_user(username)
|
||||
for e in priv_share_in:
|
||||
e.file_or_dir = os.path.basename(e.path.rstrip('/'))
|
||||
e.out_or_in = 'in'
|
||||
e.repo = seafile_api.get_repo(e.repo_id)
|
||||
priv_shares = list(priv_share_out) + list(priv_share_in)
|
||||
|
||||
return render_to_response('repo/share_admin.html', {
|
||||
"org": None,
|
||||
"shared_repos": shared_repos,
|
||||
# "out_links": out_links,
|
||||
"fileshares": p_fileshares,
|
||||
"priv_shares": priv_shares,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
|
@@ -117,7 +117,7 @@
|
||||
<div class="displayed-op">
|
||||
<a class="op" href="{% url 'repo_download_dir' repo.id %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{% trans 'Download' %}</a>
|
||||
{% if not repo.encrypted %}
|
||||
<a class="op file-share" href="#" data-name="{{ dirent.obj_name }}" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}" data-type="d">{% trans "Share" %}</a>
|
||||
<a class="op file-share" href="#" data-name="{{ dirent.obj_name }}" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}" data-type="d" data-path="{{path}}{{dirent.obj_name}}">{% trans "Share" %}</a>
|
||||
{% endif %}
|
||||
{% if ENABLE_SUB_LIBRARY and not repo.is_virtual %}
|
||||
<a class="op create-sub-repo" href="#" data-name="{{ dirent.obj_name }}">{% trans "Sub-library" %}</a>
|
||||
@@ -166,7 +166,7 @@
|
||||
{% if user_perm == 'rw' %}
|
||||
<a class="op update-file" data-target="{{ path }}{{dirent.obj_name}}" href="#">{% trans "Update"%}</a>
|
||||
{% if not repo.encrypted %}
|
||||
<a class="op file-share" href="#" data-name="{{ dirent.obj_name }}" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}">{% trans "Share" %}</a>
|
||||
<a class="op file-share" href="#" data-name="{{ dirent.obj_name }}" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}" data-type="f" data-path="{{path}}{{dirent.obj_name}}" >{% trans "Share" %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -328,6 +328,29 @@
|
||||
|
||||
<div id="file-share" class="hide">
|
||||
<h3>{% trans 'Share' %} <span class="op-target"></span></h3>
|
||||
|
||||
<div id="repo-share-tabs">
|
||||
<ul id="repo-share-tabs-nav">
|
||||
<li><a href="#private-share">{% trans "Private share" %}</a></li>
|
||||
<li><a href="#shared-link">{% trans "Shared link" %}</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="private-share">
|
||||
<form id="private-share-form" method="post" action="{% url 'private_file_share' repo.id %}">{% csrf_token %}
|
||||
<textarea id="emails" name="emails" class="w100" placeholder="{% trans "Emails seperated by ','"%}"></textarea>
|
||||
<select name="perm" class="share-permission-select w100">
|
||||
<option value="rw" selected="selected">{% trans "Read-Write"%}</option>
|
||||
<option value="r">{% trans "Read-Only"%}</option>
|
||||
</select>
|
||||
|
||||
<input type="hidden" name="repo_id" value="" />
|
||||
<input type="hidden" name="s_type" value="" />
|
||||
<input type="hidden" name="path" value="" />
|
||||
<p class="tip">{% trans 'Tip: must be a registered user.' %}</p>
|
||||
<input type="submit" value="{% trans "Submit"%}" />
|
||||
</form>
|
||||
</div> <!--/#private-share-->
|
||||
<div id="shared-link">
|
||||
<p>{% trans 'Link: ' %}<input type="text" readonly="readonly" id="shared-link-text" /></p>
|
||||
<button id="send-link">{% trans 'Send' %}</button>
|
||||
<form id="link-send-form" action="" method="post" class="hide">{% csrf_token %}
|
||||
@@ -338,7 +361,9 @@
|
||||
<p class="error hide"></p>
|
||||
<p id="sending" class="hide">{% trans "Sending..."%}</p>
|
||||
</form>
|
||||
</div>
|
||||
</div> <!--/#shared-link-->
|
||||
</div> <!--/#repo-share-tabs-->
|
||||
</div> <!--/#file-share-->
|
||||
|
||||
{% with attach_type='dir' %}
|
||||
{% include "snippets/group_recommend_form.html" %}
|
||||
@@ -656,6 +681,15 @@ $('.file-star').click(function() {
|
||||
|
||||
//file share
|
||||
$('.file-share').click(function() {
|
||||
$("#private-share-form input[name=s_type]").val($(this).data('type'));
|
||||
$("#private-share-form input[name=path]").val($(this).data('path'));
|
||||
var contacts = [];
|
||||
{% for contact in contacts %}
|
||||
contact_email = '{{ contact.contact_email }}';
|
||||
contacts.push({value:contact_email, label:contact_email});
|
||||
{% endfor %}
|
||||
addAutocomplete('#emails', '#private-share-form', contacts);
|
||||
|
||||
var filename = $(this).data('name');
|
||||
function showPopup(link) {
|
||||
$('#file-share .op-target').html(trimFilename(filename, 30));
|
||||
@@ -663,6 +697,7 @@ $('.file-share').click(function() {
|
||||
$('#main').append('<p id="linkwidth" class="hide">' + link + '</p>');
|
||||
$('#shared-link-text').css({'width':$('#linkwidth').width() + 2});
|
||||
$('#file-share').modal({'focus':false}); // in ff: if 'focus' is true, 'shared-link-text' gets the focus
|
||||
$("#repo-share-tabs").tabs();
|
||||
$('#linkwidth').remove();
|
||||
$('#simplemodal-container').css({'height':'auto'});
|
||||
}
|
||||
|
@@ -42,7 +42,6 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bot">
|
||||
<select name="permission" class="share-permission-select w100">
|
||||
<option value="rw" selected="selected">{% trans "Read-Write"%}</option>
|
||||
|
@@ -5,7 +5,7 @@ from django.conf import settings
|
||||
from seahub.views import *
|
||||
from seahub.views.file import view_file, view_history_file, view_trash_file,\
|
||||
view_snapshot_file, file_edit, view_shared_file, view_file_via_shared_dir,\
|
||||
text_diff
|
||||
text_diff, private_file_share, rm_private_file_share
|
||||
from seahub.views.repo import repo, repo_history_view
|
||||
from notifications.views import notification_list
|
||||
from group.views import group_list
|
||||
@@ -80,7 +80,9 @@ urlpatterns = patterns('',
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/trash/files/$', view_trash_file, name="view_trash_file"),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/snapshot/files/$', view_snapshot_file, name="view_snapshot_file"),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/file/edit/$', file_edit, name='file_edit'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/(?P<obj_id>[^/]+)/$', repo_access_file, name='repo_access_file'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/privshare/$', private_file_share, name='private_file_share'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/privshare/remove/$', rm_private_file_share, name='rm_private_file_share'),
|
||||
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/(?P<obj_id>[0-9a-f]{40})/$', repo_access_file, name='repo_access_file'),
|
||||
(r'^repo/save_settings$', repo_save_settings),
|
||||
url(r'^repo/create_sub_repo/$', create_sub_repo, name='create_sub_repo'),
|
||||
|
||||
|
@@ -166,6 +166,18 @@ def calculate_repo_last_modify(repo_list):
|
||||
cmmts = get_commits(repo.id, 0, 1)
|
||||
repo.latest_modify = cmmts[0].ctime if cmmts else 0
|
||||
|
||||
def normalize_dir_path(path):
|
||||
"""Add '/' at the end of directory path if necessary.
|
||||
"""
|
||||
if path[-1] != '/':
|
||||
path = path + '/'
|
||||
return path
|
||||
|
||||
def normalize_file_path(path):
|
||||
"""Remove '/' at the end of file path if necessary.
|
||||
"""
|
||||
return path.rstrip('/')
|
||||
|
||||
def check_filename_with_rename(repo_id, parent_dir, filename):
|
||||
cmmts = get_commits(repo_id, 0, 1)
|
||||
latest_commit = cmmts[0] if cmmts else None
|
||||
|
@@ -13,6 +13,7 @@ import chardet
|
||||
import logging
|
||||
|
||||
from django.contrib.sites.models import Site, RequestSite
|
||||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db.models import F
|
||||
from django.http import HttpResponse, HttpResponseBadRequest, Http404, \
|
||||
@@ -23,6 +24,7 @@ from django.template.loader import render_to_string
|
||||
from django.utils.hashcompat import md5_constructor
|
||||
from django.utils.http import urlquote
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.template.defaultfilters import filesizeformat
|
||||
|
||||
from seaserv import seafile_api
|
||||
@@ -36,7 +38,7 @@ from seahub.auth.decorators import login_required
|
||||
from seahub.base.decorators import repo_passwd_set_required
|
||||
from seahub.base.models import UuidObjidMap
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.share.models import FileShare, PrivateFileDirShare
|
||||
from seahub.wiki.utils import get_wiki_dirent
|
||||
from seahub.wiki.models import WikiDoesNotExist, WikiPageMissing
|
||||
from seahub.utils import get_httpserver_root, show_delete_days, render_error, \
|
||||
@@ -45,8 +47,8 @@ from seahub.utils import get_httpserver_root, show_delete_days, render_error, \
|
||||
is_textual_file, show_delete_days, mkstemp, EMPTY_SHA1, HtmlDiff
|
||||
from seahub.utils.file_types import (IMAGE, PDF, IMAGE, DOCUMENT, MARKDOWN, \
|
||||
TEXT, SF)
|
||||
|
||||
from seahub.utils import HAS_OFFICE_CONVERTER
|
||||
from seahub.views import is_registered_user
|
||||
|
||||
if HAS_OFFICE_CONVERTER:
|
||||
from seahub.utils import query_office_convert_status, query_office_file_pages, \
|
||||
@@ -147,19 +149,41 @@ def repo_file_get(raw_path, file_enc):
|
||||
|
||||
return err, file_content, encoding
|
||||
|
||||
def get_file_view_path_and_perm(request, repo_id, obj_id, filename):
|
||||
def check_file_access_permission(username, repo_id, path):
|
||||
"""Check user has permission to view the file.
|
||||
1. check whether this file is private shared.
|
||||
2. if failed, check whether the parent of this directory is private shared.
|
||||
"""
|
||||
|
||||
pfs = PrivateFileDirShare.objects.get_private_share_in_file(username,
|
||||
repo_id, path)
|
||||
if pfs is None:
|
||||
dirs = PrivateFileDirShare.objects.list_private_share_in_dirs_by_user_and_repo(username, repo_id)
|
||||
for e in dirs:
|
||||
if path.startswith(e.path):
|
||||
return e.permission
|
||||
return None
|
||||
else:
|
||||
return pfs.permission
|
||||
|
||||
def check_repo_access_permission(repo_id, username):
|
||||
return seafile_api.check_repo_access_permission(repo_id, username)
|
||||
|
||||
def get_file_view_path_and_perm(request, repo_id, obj_id, path):
|
||||
"""
|
||||
Return raw path of a file and the permission to view file.
|
||||
"""
|
||||
username = request.user.username
|
||||
# check permission
|
||||
perm = get_user_permission(request, repo_id)
|
||||
if perm:
|
||||
filename = os.path.basename(path)
|
||||
|
||||
user_perm = check_file_access_permission(username, repo_id, path) or \
|
||||
check_repo_access_permission(repo_id, username)
|
||||
if user_perm is None:
|
||||
return ('', user_perm)
|
||||
else:
|
||||
# Get a token to visit file
|
||||
token = web_get_access_token(repo_id, obj_id, 'view', username)
|
||||
return (gen_file_get_url(token, filename), perm)
|
||||
else:
|
||||
return ('', perm)
|
||||
return (gen_file_get_url(token, filename), user_perm)
|
||||
|
||||
def handle_textual_file(request, filetype, raw_path, ret_dict):
|
||||
# encoding option a user chose
|
||||
@@ -284,7 +308,7 @@ def view_file(request, repo_id):
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
path = request.GET.get('p', '/')
|
||||
path = request.GET.get('p', '/').rstrip('/')
|
||||
obj_id = get_file_id_by_path(repo_id, path)
|
||||
if not obj_id:
|
||||
return render_error(request, _(u'File does not exist'))
|
||||
@@ -296,7 +320,7 @@ def view_file(request, repo_id):
|
||||
# Check whether user has permission to view file and get file raw path,
|
||||
# render error page if permission is deny.
|
||||
raw_path, user_perm = get_file_view_path_and_perm(request, repo_id,
|
||||
obj_id, u_filename)
|
||||
obj_id, path)
|
||||
if not user_perm:
|
||||
return render_permission_error(request, _(u'Unable to view file'))
|
||||
|
||||
@@ -461,7 +485,7 @@ def view_history_file_common(request, repo_id, ret_dict):
|
||||
# Check whether user has permission to view file and get file raw path,
|
||||
# render error page if permission is deny.
|
||||
raw_path, user_perm = get_file_view_path_and_perm(request, repo_id,
|
||||
obj_id, u_filename)
|
||||
obj_id, path)
|
||||
request.user_perm = user_perm
|
||||
|
||||
# get file type and extension
|
||||
@@ -1030,3 +1054,55 @@ def office_convert_query_page_num(request):
|
||||
ret['error'] = str(e)
|
||||
|
||||
return HttpResponse(json.dumps(ret), content_type=content_type)
|
||||
|
||||
###### private file/dir shares
|
||||
@require_POST
|
||||
def private_file_share(request, repo_id):
|
||||
emails = request.POST.get('emails', '')
|
||||
s_type = request.POST.get('s_type', '')
|
||||
path = request.POST.get('path', '')
|
||||
perm = request.POST.get('perm', 'r')
|
||||
file_or_dir = os.path.basename(path.rstrip('/'))
|
||||
username = request.user.username
|
||||
|
||||
for email in [e.strip() for e in emails.split(',') if e.strip()]:
|
||||
if not is_registered_user(email):
|
||||
messages.error(request, _('Failed to share to "%s", user not found.') % email)
|
||||
continue
|
||||
|
||||
if s_type == 'f':
|
||||
PrivateFileDirShare.objects.add_private_file_share(
|
||||
username, email, repo_id, path, perm)
|
||||
elif s_type == 'd':
|
||||
PrivateFileDirShare.objects.add_private_dir_share(
|
||||
username, email, repo_id, path, perm)
|
||||
else:
|
||||
assert False # todo
|
||||
messages.success(request, _('Successfully shared %s.') % file_or_dir)
|
||||
|
||||
next = request.META.get('HTTP_REFERER', None)
|
||||
if not next:
|
||||
next = SITE_ROOT
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
@login_required
|
||||
def rm_private_file_share(request, repo_id):
|
||||
"""Remove private file shares.
|
||||
"""
|
||||
from_user = request.GET.get('from', '')
|
||||
to_user = request.GET.get('to', '')
|
||||
username = request.user.username
|
||||
if username == from_user or username == to_user:
|
||||
path = request.GET.get('p')
|
||||
file_or_dir = os.path.basename(path.rstrip('/'))
|
||||
|
||||
PrivateFileDirShare.objects.delete_private_file_dir_share(
|
||||
from_user, to_user, repo_id, path)
|
||||
messages.success(request, _('Successfully unshared "%s".') % file_or_dir)
|
||||
else:
|
||||
messages.error(request, _("You don't have permission to unshared %s.") % file_or_dir)
|
||||
|
||||
next = request.META.get('HTTP_REFERER', None)
|
||||
if not next:
|
||||
next = SITE_ROOT
|
||||
return HttpResponseRedirect(next)
|
||||
|
@@ -15,7 +15,7 @@ from seaserv import seafile_api, MAX_UPLOAD_FILE_SIZE
|
||||
from seahub.auth.decorators import login_required
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.forms import RepoPassowrdForm
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.share.models import FileShare, PrivateFileDirShare
|
||||
from seahub.views import gen_path_link, get_user_permission, get_repo_dirents
|
||||
from seahub.utils import get_ccnetapplet_root, is_file_starred, \
|
||||
gen_file_upload_url, get_httpserver_root, gen_dir_share_link, \
|
||||
@@ -40,6 +40,23 @@ def list_dir_by_commit_and_path(commit, path):
|
||||
def is_password_set(repo_id, username):
|
||||
return seafile_api.is_password_set(repo_id, username)
|
||||
|
||||
def check_dir_access_permission(username, repo_id, path):
|
||||
"""Check user has permission to view the directory.
|
||||
1. check whether this directory is private shared.
|
||||
2. if failed, check whether the parent of this directory is private shared.
|
||||
"""
|
||||
|
||||
pfs = PrivateFileDirShare.objects.get_private_share_in_dir(username,
|
||||
repo_id, path)
|
||||
if pfs is None:
|
||||
dirs = PrivateFileDirShare.objects.list_private_share_in_dirs_by_user_and_repo(username, repo_id)
|
||||
for e in dirs:
|
||||
if path.startswith(e.path):
|
||||
return e.permission
|
||||
return None
|
||||
else:
|
||||
return pfs.permission
|
||||
|
||||
def check_repo_access_permission(repo_id, username):
|
||||
return seafile_api.check_repo_access_permission(repo_id, username)
|
||||
|
||||
@@ -169,7 +186,9 @@ def render_repo(request, repo):
|
||||
return permission deny page
|
||||
"""
|
||||
username = request.user.username
|
||||
user_perm = check_repo_access_permission(repo.id, username)
|
||||
path = get_path_from_request(request)
|
||||
user_perm = check_dir_access_permission(username, repo.id, path) or \
|
||||
check_repo_access_permission(repo.id, username)
|
||||
if user_perm is None:
|
||||
return render_to_response('repo_access_deny.html', {
|
||||
'repo': repo,
|
||||
@@ -189,7 +208,6 @@ def render_repo(request, repo):
|
||||
|
||||
protocol = request.is_secure() and 'https' or 'http'
|
||||
domain = RequestSite(request).domain
|
||||
path = get_path_from_request(request)
|
||||
|
||||
contacts = Contact.objects.get_contacts_by_user(username)
|
||||
accessible_repos = [repo] if repo.encrypted else get_unencry_rw_repos_by_user(username)
|
||||
@@ -278,7 +296,9 @@ def repo_history_view(request, repo_id):
|
||||
raise Http404
|
||||
|
||||
username = request.user.username
|
||||
user_perm = check_repo_access_permission(repo.id, username)
|
||||
path = get_path_from_request(request)
|
||||
user_perm = check_dir_access_permission(username, repo.id, path) or \
|
||||
check_repo_access_permission(repo.id, username)
|
||||
if user_perm is None:
|
||||
return render_to_response('repo_access_deny.html', {
|
||||
'repo': repo,
|
||||
@@ -298,7 +318,6 @@ def repo_history_view(request, repo_id):
|
||||
if not current_commit:
|
||||
current_commit = get_commit(repo.head_cmmt_id)
|
||||
|
||||
path = get_path_from_request(request)
|
||||
file_list, dir_list = get_repo_dirents(request, repo.id, current_commit, path)
|
||||
zipped = get_nav_path(path, repo.name)
|
||||
search_repo_id = None if repo.encrypted else repo.id
|
||||
|
Reference in New Issue
Block a user