mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-18 08:16:07 +00:00
Merge pull request #1198 from haiwen/share-link
update audit when view file via shared dir
This commit is contained in:
@@ -11,9 +11,10 @@ def share_link_audit(func):
|
||||
def _decorated(request, token, *args, **kwargs):
|
||||
assert token is not None # Checked by URLconf
|
||||
|
||||
fileshare = FileShare.objects.get_valid_file_link_by_token(token)
|
||||
if fileshare is None:
|
||||
fileshare = UploadLinkShare.objects.get_valid_upload_link_by_token(token)
|
||||
fileshare = FileShare.objects.get_valid_file_link_by_token(token) or \
|
||||
FileShare.objects.get_valid_dir_link_by_token(token) or \
|
||||
UploadLinkShare.objects.get_valid_upload_link_by_token(token)
|
||||
|
||||
if fileshare is None:
|
||||
raise Http404
|
||||
|
||||
|
@@ -87,7 +87,7 @@
|
||||
|
||||
<td>
|
||||
{% if dirent.is_img %}
|
||||
<a class="normal img-name-link" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}" data-mfp-src="{% url "view_raw_shared_file" token dirent.obj_id dirent.obj_name %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a>
|
||||
<a class="normal img-name-link" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}" data-mfp-src="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}&raw=1">{{ dirent.obj_name }}</a>
|
||||
{% else %}
|
||||
<a class="normal" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a>
|
||||
{% endif %}
|
||||
@@ -125,7 +125,7 @@
|
||||
{% for dirent in file_list %}
|
||||
<li class="file-item grid-item" data-name="{{dirent.obj_name}}" title="{{dirent.obj_name}}">
|
||||
{% if dirent.is_img %}
|
||||
<a class="img-link img-img-link" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}" data-mfp-src="{% url "view_raw_shared_file" token dirent.obj_id dirent.obj_name %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">
|
||||
<a class="img-link img-img-link" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}" data-mfp-src="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}&raw=1">
|
||||
{% if dirent.encoded_thumbnail_src %}
|
||||
<img class="thumbnail vam" src="{{ SITE_ROOT }}{{ dirent.encoded_thumbnail_src }}" alt="" />
|
||||
{% else %}
|
||||
@@ -139,7 +139,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if dirent.is_img %}
|
||||
<a class="normal img-name-link text-link ellipsis" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}" data-mfp-src="{% url "view_raw_shared_file" token dirent.obj_id dirent.obj_name %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a>
|
||||
<a class="normal img-name-link text-link ellipsis" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}" data-mfp-src="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}&raw=1">{{ dirent.obj_name }}</a>
|
||||
{% else %}
|
||||
<a class="normal text-link ellipsis" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a>
|
||||
{% endif %}
|
||||
|
@@ -896,14 +896,9 @@ def view_raw_shared_file(request, token, obj_id, file_name):
|
||||
outer_url = gen_file_get_url(token, filename)
|
||||
return HttpResponseRedirect(outer_url)
|
||||
|
||||
def view_file_via_shared_dir(request, token):
|
||||
assert token is not None # Checked by URLconf
|
||||
|
||||
fileshare = FileShare.objects.get_valid_file_link_by_token(token)
|
||||
if fileshare is None:
|
||||
raise Http404
|
||||
|
||||
|
||||
@share_link_audit
|
||||
def view_file_via_shared_dir(request, fileshare):
|
||||
token = fileshare.token
|
||||
req_path = request.GET.get('p', '').rstrip('/')
|
||||
if not req_path:
|
||||
return HttpResponseRedirect(reverse('view_shared_dir', args=[token]))
|
||||
@@ -941,9 +936,19 @@ def view_file_via_shared_dir(request, token):
|
||||
obj_id = seafile_api.get_file_id_by_path(repo_id, real_path)
|
||||
if not obj_id:
|
||||
return render_error(request, _(u'File does not exist'))
|
||||
file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)
|
||||
|
||||
filename = os.path.basename(req_path)
|
||||
if request.GET.get('raw', '0') == '1':
|
||||
username = request.user.username
|
||||
token = seafile_api.get_fileserver_access_token(repo_id,
|
||||
obj_id, 'view', username, use_onetime=True)
|
||||
|
||||
raw_url = gen_file_get_url(token, filename)
|
||||
# send stats message
|
||||
send_file_access_msg(request, repo, real_path, 'share-link')
|
||||
return HttpResponseRedirect(raw_url)
|
||||
|
||||
file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)
|
||||
filetype, fileext = get_file_type_and_ext(filename)
|
||||
access_token = seafile_api.get_fileserver_access_token(repo.id, obj_id,
|
||||
'view', '', use_onetime=False)
|
||||
|
143
tests/seahub/share/test_decorators.py
Normal file
143
tests/seahub/share/test_decorators.py
Normal file
@@ -0,0 +1,143 @@
|
||||
from mock import patch
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.test import override_settings
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from seahub.test_utils import BaseTestCase
|
||||
from seahub.share.decorators import share_link_audit
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.utils import gen_token, normalize_cache_key
|
||||
|
||||
class ShareLinkAuditTest(BaseTestCase):
|
||||
def setUp(self):
|
||||
share_file_info = {
|
||||
'username': self.user.username,
|
||||
'repo_id': self.repo.id,
|
||||
'path': self.file,
|
||||
'password': None,
|
||||
'expire_date': None,
|
||||
}
|
||||
self.fs = FileShare.objects.create_file_link(**share_file_info)
|
||||
|
||||
# Every test needs access to the request factory.
|
||||
self.factory = RequestFactory()
|
||||
|
||||
@property
|
||||
def _request(self, session={}):
|
||||
request = self.factory.get('/rand')
|
||||
request.user = self.user
|
||||
request.session = session
|
||||
return request
|
||||
|
||||
def _anon_request(self, session={}):
|
||||
request = self.factory.get('/rand')
|
||||
request.user = AnonymousUser()
|
||||
request.session = session
|
||||
request.cloud_mode = False
|
||||
return request
|
||||
|
||||
def _anon_post_request(self, data={}, session={}):
|
||||
request = self.factory.post('/rand', data)
|
||||
request.user = AnonymousUser()
|
||||
request.session = session
|
||||
request.cloud_mode = False
|
||||
return request
|
||||
|
||||
def _fake_view_shared_file(self, request, token):
|
||||
@share_link_audit
|
||||
def fake_view_shared_file(request, fileshare):
|
||||
return HttpResponse()
|
||||
return fake_view_shared_file(request, token)
|
||||
|
||||
def test_bad_share_token(self):
|
||||
@share_link_audit
|
||||
def a_view(request, fileshare):
|
||||
return HttpResponse()
|
||||
|
||||
request = self.factory.get('/rand')
|
||||
request.user = self.user
|
||||
|
||||
self.assertRaises(Http404, a_view, request, 'xxx')
|
||||
|
||||
def test_non_pro_version(self):
|
||||
"""
|
||||
Check that share_link_audit works as nomal view_shared_file on
|
||||
non-pro version.
|
||||
"""
|
||||
resp = self._fake_view_shared_file(self._request, self.fs.token)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
def test_shared_link_audit_not_enabled(self):
|
||||
resp = self._fake_view_shared_file(self._request, self.fs.token)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@override_settings(ENABLE_SHARE_LINK_AUDIT=True)
|
||||
@patch('seahub.share.decorators.is_pro_version')
|
||||
def test_audit_authenticated_user(self, mock_is_pro_version):
|
||||
mock_is_pro_version.return_value = True
|
||||
|
||||
resp = self._fake_view_shared_file(self._request, self.fs.token)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@override_settings(ENABLE_SHARE_LINK_AUDIT=True)
|
||||
@patch('seahub.share.decorators.is_pro_version')
|
||||
def test_audit_anonymous_user_with_mail_in_session(self, mock_is_pro_version):
|
||||
mock_is_pro_version.return_value = True
|
||||
|
||||
anon_req = self._anon_request(session={'anonymous_email': 'a@a.com'})
|
||||
resp = self._fake_view_shared_file(anon_req, self.fs.token)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@override_settings(ENABLE_SHARE_LINK_AUDIT=True)
|
||||
@patch('seahub.share.decorators.is_pro_version')
|
||||
def test_audit_anonymous_user_without_mail_in_session(self, mock_is_pro_version):
|
||||
"""
|
||||
Check that share_link_audit works on pro version and setting enabled,
|
||||
which show a page that let user input email and verification code.
|
||||
"""
|
||||
mock_is_pro_version.return_value = True
|
||||
|
||||
anon_req = self._anon_request()
|
||||
resp = self._fake_view_shared_file(anon_req, self.fs.token)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn('<p class="tip">Please provide your email address to continue.</p>', resp.content)
|
||||
|
||||
@override_settings(ENABLE_SHARE_LINK_AUDIT=True)
|
||||
@patch('seahub.share.decorators.is_pro_version')
|
||||
def test_anonymous_user_post_wrong_token(self, mock_is_pro_version):
|
||||
"""
|
||||
Check that anonnymous user input email and wrong verification code.
|
||||
"""
|
||||
mock_is_pro_version.return_value = True
|
||||
|
||||
anon_req = self._anon_post_request(data={'code': 'xx'}, session={})
|
||||
self.assertEqual(anon_req.session.get('anonymous_email'), None)
|
||||
resp = self._fake_view_shared_file(anon_req, self.fs.token)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn('Invalid token, please try again.', resp.content)
|
||||
|
||||
@override_settings(ENABLE_SHARE_LINK_AUDIT=True)
|
||||
@patch('seahub.share.decorators.is_pro_version')
|
||||
def test_anonymous_user_post_correct_token(self, mock_is_pro_version):
|
||||
"""
|
||||
Check that anonnymous user input email and correct verification code.
|
||||
"""
|
||||
mock_is_pro_version.return_value = True
|
||||
|
||||
code = gen_token(max_length=6)
|
||||
email = 'a@a.com'
|
||||
cache_key = normalize_cache_key(email, 'share_link_audit_')
|
||||
cache.set(cache_key, code, timeout=60)
|
||||
assert cache.get(cache_key) == code
|
||||
|
||||
anon_req = self._anon_post_request(data={'code': code, 'email': email})
|
||||
self.assertEqual(anon_req.session.get('anonymous_email'), None)
|
||||
resp = self._fake_view_shared_file(anon_req, self.fs.token)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(anon_req.session.get('anonymous_email'), email) # email is set in session
|
||||
assert cache.get(cache_key) is None # token is delete after used
|
@@ -38,6 +38,13 @@ class SharedDirTest(TestCase, Fixtures):
|
||||
self.assertEqual(302, resp.status_code)
|
||||
assert '8082/files/' in resp.get('location')
|
||||
|
||||
def test_view_raw_file_via_shared_dir(self):
|
||||
resp = self.client.get(
|
||||
reverse('view_file_via_shared_dir', args=[self.fs.token]) + '?p=' + self.file + '&raw=1'
|
||||
)
|
||||
|
||||
assert '8082' in resp['location']
|
||||
|
||||
class EncryptSharedDirTest(TestCase, Fixtures):
|
||||
def setUp(self):
|
||||
share_file_info = {
|
||||
@@ -124,6 +131,24 @@ class EncryptSharedDirTest(TestCase, Fixtures):
|
||||
self.assertTemplateUsed(resp, 'shared_file_view.html')
|
||||
self.assertContains(resp, '%s</h2>' % self.filename)
|
||||
|
||||
def test_view_raw_file_via_shared_dir(self):
|
||||
resp = self.client.post(
|
||||
reverse('view_file_via_shared_dir', args=[self.fs.token]) + '?p=' + self.sub_file, {
|
||||
'password': '12345678'
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateNotUsed(resp, 'share_access_validation.html')
|
||||
self.assertTemplateUsed(resp, 'shared_file_view.html')
|
||||
self.assertContains(resp, '%s</h2>' % self.filename)
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('view_file_via_shared_dir', args=[self.fs.token]) + '?p=' + self.sub_file + '&raw=1'
|
||||
)
|
||||
|
||||
assert '8082' in resp['location']
|
||||
|
||||
def test_view_file_via_shared_dir_without_password(self):
|
||||
resp = self.client.get(
|
||||
reverse('view_file_via_shared_dir', args=[self.fs.token]) + '?p=' + self.sub_file
|
||||
|
Reference in New Issue
Block a user