mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-16 07:08:55 +00:00
[share] Update share link passwd
This commit is contained in:
@@ -437,9 +437,6 @@ SESSION_COOKIE_AGE = 24 * 60 * 60
|
||||
# Days of remembered login info (deafult: 7 days)
|
||||
LOGIN_REMEMBER_DAYS = 7
|
||||
|
||||
#Share Access
|
||||
SHARE_ACCESS_PASSWD_TIMEOUT = 60 * 60
|
||||
|
||||
SEAFILE_VERSION = '5.0.0'
|
||||
|
||||
# Compress static files(css, js)
|
||||
|
@@ -1,14 +1,16 @@
|
||||
import datetime
|
||||
from django.core.cache import cache
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.contrib.auth.hashers import make_password
|
||||
|
||||
from seahub.base.fields import LowerCaseCharField
|
||||
from seahub.utils import normalize_file_path, normalize_dir_path, gen_token, \
|
||||
normalize_cache_key
|
||||
from seahub.utils.ip import get_remote_ip
|
||||
from seahub.settings import SHARE_ACCESS_PASSWD_TIMEOUT
|
||||
from seahub.utils import normalize_file_path, normalize_dir_path, gen_token
|
||||
|
||||
# Get an instance of a logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AnonymousShare(models.Model):
|
||||
"""
|
||||
@@ -19,37 +21,31 @@ class AnonymousShare(models.Model):
|
||||
anonymous_email = LowerCaseCharField(max_length=255)
|
||||
token = models.CharField(max_length=25, unique=True)
|
||||
|
||||
def _get_cache_key(request, prefix, token):
|
||||
"""Return cache key of certain ``prefix``. If user is logged in, use
|
||||
username and token, otherwise use combination of request ip and user agent
|
||||
and token.
|
||||
def _get_link_key(token, is_upload_link=False):
|
||||
return 'visited_ufs_' + token if is_upload_link else \
|
||||
'visited_fs_' + token
|
||||
|
||||
Arguments:
|
||||
- `prefix`:
|
||||
"""
|
||||
if request.user.is_authenticated():
|
||||
key = normalize_cache_key(request.user.username, 'SharedLink_', token)
|
||||
else:
|
||||
ip = get_remote_ip(request)
|
||||
# Memcached key length limit is 250 chars, and user agent sometimes may
|
||||
# be long which will cause error.
|
||||
agent = request.META.get('HTTP_USER_AGENT', '')[:150]
|
||||
key = normalize_cache_key(ip + agent, 'SharedLink_', token)
|
||||
|
||||
return key
|
||||
|
||||
def set_share_link_access(request, token):
|
||||
"""Remember which share download/upload links user can access without
|
||||
def set_share_link_access(request, token, is_upload_link=False):
|
||||
"""Remember which shared download/upload link user can access without
|
||||
providing password.
|
||||
"""
|
||||
key = _get_cache_key(request, 'SharedLink_', token)
|
||||
cache.set(key, True, SHARE_ACCESS_PASSWD_TIMEOUT)
|
||||
if request.session:
|
||||
link_key = _get_link_key(token, is_upload_link)
|
||||
request.session[link_key] = True
|
||||
else:
|
||||
# should never reach here in normal case
|
||||
logger.warn('Failed to remember shared link password, request.session'
|
||||
' is None when set shared link access.')
|
||||
|
||||
def check_share_link_access(request, token):
|
||||
"""Check whether user can access share link without providing password.
|
||||
def check_share_link_access(request, token, is_upload_link=False):
|
||||
"""Check whether user can access shared download/upload link without
|
||||
providing password.
|
||||
"""
|
||||
key = _get_cache_key(request, 'SharedLink_', token)
|
||||
return cache.get(key, False)
|
||||
link_key = _get_link_key(token, is_upload_link)
|
||||
if request.session.get(link_key, False):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
class FileShareManager(models.Manager):
|
||||
def _add_file_share(self, username, repo_id, path, s_type,
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{% block main_panel %}
|
||||
<div class="wide-panel">
|
||||
<p class="access-notice">{% trans "Please input the password if you want to browse the shared file/directory. And the password will be kept on the server for only 1 hour." %}</p>
|
||||
<p class="access-notice">{% trans "Please input the password if you want to browse the shared file/directory." %}</p>
|
||||
<form action="{% url view_name token %}" method="post" id="share-passwd-form">{% csrf_token %}
|
||||
<label>{% trans "Password: " %}</label>
|
||||
<input type="password" name="password" autofocus />
|
||||
|
@@ -519,7 +519,8 @@ def view_shared_upload_link(request, token):
|
||||
if uploadlink is None:
|
||||
raise Http404
|
||||
|
||||
if uploadlink.is_encrypted() and not check_share_link_access(request, token):
|
||||
if uploadlink.is_encrypted() and not check_share_link_access(
|
||||
request, token, is_upload_link=True):
|
||||
d = {'token': token, 'view_name': 'view_shared_upload_link', }
|
||||
if request.method == 'POST':
|
||||
post_values = request.POST.copy()
|
||||
@@ -527,7 +528,7 @@ def view_shared_upload_link(request, token):
|
||||
form = SharedLinkPasswordForm(post_values)
|
||||
d['form'] = form
|
||||
if form.is_valid():
|
||||
set_share_link_access(request, token)
|
||||
set_share_link_access(request, token, is_upload_link=True)
|
||||
else:
|
||||
return render_to_response('share_access_validation.html', d,
|
||||
context_instance=RequestContext(request))
|
||||
|
@@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.test import TestCase
|
||||
import requests
|
||||
|
||||
from seahub.share.models import FileShare, PrivateFileDirShare
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.test_utils import Fixtures
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class SharedFileTest(TestCase, Fixtures):
|
||||
|
||||
def setUp(self):
|
||||
share_file_info = {
|
||||
'username': 'test@test.com',
|
||||
'username': self.user,
|
||||
'repo_id': self.repo.id,
|
||||
'path': self.file,
|
||||
'password': None,
|
||||
@@ -21,6 +21,13 @@ class SharedFileTest(TestCase, Fixtures):
|
||||
}
|
||||
self.fs = FileShare.objects.create_file_link(**share_file_info)
|
||||
|
||||
share_file_info.update({'password': '12345678'})
|
||||
self.enc_fs = FileShare.objects.create_file_link(**share_file_info)
|
||||
share_file_info.update({'password': '12345678'})
|
||||
self.enc_fs2 = FileShare.objects.create_file_link(**share_file_info)
|
||||
|
||||
assert self.enc_fs.token != self.enc_fs2.token
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
@@ -99,6 +106,47 @@ class SharedFileTest(TestCase, Fixtures):
|
||||
resp = self.client.get(reverse('view_shared_file', args=[fs.token]))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
def _assert_redirect_to_password_page(self, fs):
|
||||
resp = self.client.get(reverse('view_shared_file', args=[fs.token]))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'share_access_validation.html')
|
||||
|
||||
def _assert_render_file_page_when_input_passwd(self, fs):
|
||||
resp = self.client.post(reverse('view_shared_file', args=[fs.token]), {
|
||||
'password': '12345678',
|
||||
})
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'shared_file_view.html')
|
||||
self.assertContains(resp, os.path.basename(self.file))
|
||||
dl_url_tag = '<a href="?dl=1" class="obv-btn">'
|
||||
self.assertContains(resp, dl_url_tag)
|
||||
|
||||
def _assert_render_file_page_without_passwd(self, fs):
|
||||
resp = self.client.get(reverse('view_shared_file', args=[fs.token]))
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'shared_file_view.html')
|
||||
|
||||
def test_can_view_enc(self):
|
||||
self._assert_redirect_to_password_page(self.enc_fs)
|
||||
self._assert_render_file_page_when_input_passwd(self.enc_fs)
|
||||
|
||||
def test_can_view_enc_link_without_passwd(self):
|
||||
self._assert_redirect_to_password_page(self.enc_fs)
|
||||
self._assert_render_file_page_when_input_passwd(self.enc_fs)
|
||||
self._assert_render_file_page_without_passwd(self.enc_fs)
|
||||
|
||||
def test_can_view_multiple_enc_links_without_passwd(self):
|
||||
# first shared link
|
||||
self._assert_redirect_to_password_page(self.enc_fs)
|
||||
self._assert_render_file_page_when_input_passwd(self.enc_fs)
|
||||
|
||||
# second shared link
|
||||
self._assert_redirect_to_password_page(self.enc_fs2)
|
||||
self._assert_render_file_page_when_input_passwd(self.enc_fs2)
|
||||
|
||||
self._assert_render_file_page_without_passwd(self.enc_fs)
|
||||
self._assert_render_file_page_without_passwd(self.enc_fs2)
|
||||
|
||||
|
||||
class FileViaSharedDirTest(TestCase, Fixtures):
|
||||
def setUp(self):
|
||||
|
51
tests/seahub/views/test_shared_upload_link.py
Normal file
51
tests/seahub/views/test_shared_upload_link.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from seahub.share.models import UploadLinkShare
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
class SharedUploadLinkTest(BaseTestCase):
|
||||
def setUp(self):
|
||||
share_file_info = {
|
||||
'username': self.user,
|
||||
'repo_id': self.repo.id,
|
||||
'path': '/',
|
||||
'password': None,
|
||||
'expire_date': None,
|
||||
}
|
||||
self.fs = UploadLinkShare.objects.create_upload_link_share(**share_file_info)
|
||||
|
||||
share_file_info.update({'password': '12345678'})
|
||||
self.enc_fs = UploadLinkShare.objects.create_upload_link_share(**share_file_info)
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
def test_can_render(self):
|
||||
resp = self.client.get(
|
||||
reverse('view_shared_upload_link', args=[self.fs.token])
|
||||
)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'view_shared_upload_link.html')
|
||||
self.assertContains(resp, "Add Files")
|
||||
|
||||
def test_can_render_enc(self):
|
||||
resp = self.client.get(
|
||||
reverse('view_shared_upload_link', args=[self.enc_fs.token])
|
||||
)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'share_access_validation.html')
|
||||
|
||||
resp = self.client.post(reverse('view_shared_upload_link',
|
||||
args=[self.enc_fs.token]), {
|
||||
'password': '12345678',
|
||||
}
|
||||
)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'view_shared_upload_link.html')
|
||||
self.assertContains(resp, "Add Files")
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('view_shared_upload_link', args=[self.enc_fs.token])
|
||||
)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'view_shared_upload_link.html')
|
Reference in New Issue
Block a user