1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-10 11:21:29 +00:00

upload with invalid type

This commit is contained in:
zming
2018-01-03 11:07:16 +08:00
parent e681752310
commit 295b567b84
12 changed files with 234 additions and 40 deletions

View File

@@ -13,6 +13,9 @@ from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error from seahub.api2.utils import api_error
from seahub.settings import SEAHUB_DATA_ROOT, MEDIA_ROOT, \ from seahub.settings import SEAHUB_DATA_ROOT, MEDIA_ROOT, \
CUSTOM_FAVICON_PATH CUSTOM_FAVICON_PATH
from seahub.utils import get_file_type_and_ext, PREVIEW_FILEEXT
from seahub.utils.file_types import IMAGE
from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -26,7 +29,16 @@ class AdminFavicon(APIView):
favicon_file = request.FILES.get('favicon', None) favicon_file = request.FILES.get('favicon', None)
if not favicon_file: if not favicon_file:
error_msg = 'favicon invalid.' error_msg = 'Favicon can not be found.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
file_type, ext = get_file_type_and_ext(favicon_file.name)
if file_type != IMAGE:
error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get(IMAGE))
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if favicon_file.size > 1024 * 1024 * 20: # 20mb
error_msg = file_size_error_msg(favicon_file.size, 20*1024*1024)
return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not os.path.exists(SEAHUB_DATA_ROOT): if not os.path.exists(SEAHUB_DATA_ROOT):

View File

@@ -13,6 +13,8 @@ from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error from seahub.api2.utils import api_error
from seahub.settings import LICENSE_PATH from seahub.settings import LICENSE_PATH
from seahub.utils import get_file_type_and_ext
from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -25,7 +27,16 @@ class AdminLicense(APIView):
def post(self, request): def post(self, request):
license_file = request.FILES.get('license', None) license_file = request.FILES.get('license', None)
if not license_file: if not license_file:
error_msg = 'license invalid.' error_msg = 'license can not be found.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
file_type, ext = get_file_type_and_ext(license_file.name)
if file_type != 'txt':
error_msg = file_type_error_msg(ext, 'txt')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if license_file.size > 1024 * 1024 * 5: # 5mb
error_msg = file_size_error_msg(license_file.size, 5*1024*1024)
return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
license_dir = os.path.dirname(LICENSE_PATH) license_dir = os.path.dirname(LICENSE_PATH)

View File

@@ -13,6 +13,9 @@ from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error from seahub.api2.utils import api_error
from seahub.settings import SEAHUB_DATA_ROOT, MEDIA_ROOT from seahub.settings import SEAHUB_DATA_ROOT, MEDIA_ROOT
from seahub.utils.auth import get_custom_login_bg_image_path from seahub.utils.auth import get_custom_login_bg_image_path
from seahub.utils import get_file_type_and_ext, PREVIEW_FILEEXT
from seahub.utils.file_types import IMAGE
from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -27,12 +30,21 @@ class AdminLoginBgImage(APIView):
def post(self, request): def post(self, request):
image_file = request.FILES.get('login_bg_image', None) image_file = request.FILES.get('login_bg_image', None)
if not image_file: if not image_file:
error_msg = 'background image invalid' error_msg = 'Image can not be found.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not os.path.exists(SEAHUB_DATA_ROOT): if not os.path.exists(SEAHUB_DATA_ROOT):
os.makedirs(SEAHUB_DATA_ROOT) os.makedirs(SEAHUB_DATA_ROOT)
file_type, ext = get_file_type_and_ext(image_file.name)
if file_type != IMAGE:
error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get('Image'))
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if image_file.size > 1024 * 1024 * 20: # 20mb
error_msg = file_size_error_msg(image_file.size, 20*1024*1024)
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
custom_login_bg_image_path = get_custom_login_bg_image_path() custom_login_bg_image_path = get_custom_login_bg_image_path()
custom_dir = os.path.join(SEAHUB_DATA_ROOT, custom_dir = os.path.join(SEAHUB_DATA_ROOT,
os.path.dirname(custom_login_bg_image_path)) os.path.dirname(custom_login_bg_image_path))

View File

@@ -14,6 +14,9 @@ from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error from seahub.api2.utils import api_error
from seahub.settings import SEAHUB_DATA_ROOT, MEDIA_ROOT, \ from seahub.settings import SEAHUB_DATA_ROOT, MEDIA_ROOT, \
CUSTOM_LOGO_PATH CUSTOM_LOGO_PATH
from seahub.utils import get_file_type_and_ext, PREVIEW_FILEEXT
from seahub.utils.file_types import IMAGE
from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -27,7 +30,17 @@ class AdminLogo(APIView):
logo_file = request.FILES.get('logo', None) logo_file = request.FILES.get('logo', None)
if not logo_file: if not logo_file:
error_msg = 'logo invalid.' error_msg = 'Logo can not be found.'
logger.error(error_msg)
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
file_type, ext = get_file_type_and_ext(logo_file.name)
if file_type != IMAGE:
error_msg = file_type_error_msg(ext, PREVIEW_FILEEXT.get(IMAGE))
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if logo_file.size > 1024 * 1024 * 20: # 20mb
error_msg = file_size_error_msg(logo_file.size, 20*1024*1024)
return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not os.path.exists(SEAHUB_DATA_ROOT): if not os.path.exists(SEAHUB_DATA_ROOT):

View File

@@ -5,11 +5,11 @@ from django import forms
from django.forms import widgets from django.forms import widgets
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.template.defaultfilters import filesizeformat
from seahub.avatar.models import Avatar from seahub.avatar.models import Avatar
from seahub.avatar.settings import (AVATAR_MAX_AVATARS_PER_USER, AVATAR_MAX_SIZE, from seahub.avatar.settings import (AVATAR_MAX_AVATARS_PER_USER, AVATAR_MAX_SIZE,
AVATAR_ALLOWED_FILE_EXTS, AVATAR_DEFAULT_SIZE) AVATAR_ALLOWED_FILE_EXTS, AVATAR_DEFAULT_SIZE)
from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg
def avatar_img(avatar, size): def avatar_img(avatar, size):
@@ -31,13 +31,11 @@ class UploadAvatarForm(forms.Form):
if AVATAR_ALLOWED_FILE_EXTS: if AVATAR_ALLOWED_FILE_EXTS:
(root, ext) = os.path.splitext(data.name.lower()) (root, ext) = os.path.splitext(data.name.lower())
if ext not in AVATAR_ALLOWED_FILE_EXTS: if ext not in AVATAR_ALLOWED_FILE_EXTS:
raise forms.ValidationError( error_msg = file_type_error_msg(ext, AVATAR_ALLOWED_FILE_EXTS)
_(u"%(ext)s is an invalid file extension. Authorized extensions are : %(valid_exts_list)s") % raise forms.ValidationError(error_msg)
{ 'ext' : ext, 'valid_exts_list' : ", ".join(AVATAR_ALLOWED_FILE_EXTS) })
if data.size > AVATAR_MAX_SIZE: if data.size > AVATAR_MAX_SIZE:
raise forms.ValidationError( error_msg = file_size_error_msg(data.size, AVATAR_MAX_SIZE)
_(u"Your file is too big (%(size)s), the maximum allowed size is %(max_valid_size)s") % raise forms.ValidationError(error_msg)
{ 'size' : filesizeformat(data.size), 'max_valid_size' : filesizeformat(AVATAR_MAX_SIZE)} )
count = Avatar.objects.filter(emailuser=self.emailuser).count() count = Avatar.objects.filter(emailuser=self.emailuser).count()
if AVATAR_MAX_AVATARS_PER_USER > 1 and \ if AVATAR_MAX_AVATARS_PER_USER > 1 and \
count >= AVATAR_MAX_AVATARS_PER_USER: count >= AVATAR_MAX_AVATARS_PER_USER:
@@ -54,13 +52,11 @@ class GroupAvatarForm(forms.Form):
if AVATAR_ALLOWED_FILE_EXTS: if AVATAR_ALLOWED_FILE_EXTS:
(root, ext) = os.path.splitext(data.name.lower()) (root, ext) = os.path.splitext(data.name.lower())
if ext not in AVATAR_ALLOWED_FILE_EXTS: if ext not in AVATAR_ALLOWED_FILE_EXTS:
raise forms.ValidationError( error_msg = file_type_error_msg(ext, AVATAR_ALLOWED_FILE_EXTS)
_(u"%(ext)s is an invalid file extension. Authorized extensions are : %(valid_exts_list)s") % raise forms.ValidationError(error_msg)
{ 'ext' : ext, 'valid_exts_list' : ", ".join(AVATAR_ALLOWED_FILE_EXTS) })
if data.size > AVATAR_MAX_SIZE: if data.size > AVATAR_MAX_SIZE:
raise forms.ValidationError( error_msg = file_size_error_msg(data.size, AVATAR_MAX_SIZE)
_(u"Your file is too big (%(size)s), the maximum allowed size is %(max_valid_size)s") % raise forms.ValidationError(error_msg)
{ 'size' : filesizeformat(data.size), 'max_valid_size' : filesizeformat(AVATAR_MAX_SIZE)})
class PrimaryAvatarForm(forms.Form): class PrimaryAvatarForm(forms.Form):

15
seahub/utils/error_msg.py Normal file
View File

@@ -0,0 +1,15 @@
from django.utils.translation import ugettext as _
from django.template.defaultfilters import filesizeformat
def file_type_error_msg(ext, allowed_file_exts):
if isinstance(allowed_file_exts, tuple) or isinstance(allowed_file_exts, list):
allowed_file_exts = ", ".join(allowed_file_exts)
return _(u"%(ext)s is an invalid file extension. Authorized extensions are " +
": %(valid_exts_list)s") % {'ext' : ext,
'valid_exts_list' : allowed_file_exts}
def file_size_error_msg(size, max_size):
return _(u"Your file is too big (%(size)s), the maximum allowed size is " +
"%(max_valid_size)s") % { 'size' : filesizeformat(size),
'max_valid_size' : filesizeformat(max_size)}

View File

@@ -37,4 +37,3 @@ def check_file_lock(repo_id, file_path, username):
return (True, True) return (True, True)
else: else:
raise SearpcError('check file lock error') raise SearpcError('check file lock error')

View File

@@ -48,6 +48,7 @@ from seahub.utils.star import get_dir_starred_files
from seahub.utils.file_types import IMAGE, VIDEO from seahub.utils.file_types import IMAGE, VIDEO
from seahub.utils.file_op import check_file_lock from seahub.utils.file_op import check_file_lock
from seahub.utils.repo import get_locked_files_by_dir from seahub.utils.repo import get_locked_files_by_dir
from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg
from seahub.base.accounts import User from seahub.base.accounts import User
from seahub.thumbnail.utils import get_thumbnail_src from seahub.thumbnail.utils import get_thumbnail_src
from seahub.share.utils import is_repo_admin from seahub.share.utils import is_repo_admin
@@ -1235,6 +1236,19 @@ def ajax_group_members_import(request, group_id):
username = request.user.username username = request.user.username
content_type = 'application/json; charset=utf-8' content_type = 'application/json; charset=utf-8'
# get and convert uploaded file
uploaded_file = request.FILES['file']
ext = os.path.splitext(uploaded_file.name)[1].lower()
if ext != '.csv':
result['error'] = file_type_error_msg(ext, "csv")
return HttpResponse(json.dumps(result), status=400,
content_type=content_type)
if uploaded_file.size > 10 * 1024 * 1024:
result['error'] = file_size_error_msg(uploaded_file.size, 10 * 1024 * 1024)
return HttpResponse(json.dumps(result), status=400,
content_type=content_type)
group_id = int(group_id) group_id = int(group_id)
try: try:
group = seaserv.get_group(group_id) group = seaserv.get_group(group_id)
@@ -1255,14 +1269,6 @@ def ajax_group_members_import(request, group_id):
return HttpResponse(json.dumps(result), status=500, return HttpResponse(json.dumps(result), status=500,
content_type=content_type) content_type=content_type)
# get and convert uploaded file
uploaded_file = request.FILES['file']
if uploaded_file.size > 10 * 1024 * 1024:
result['error'] = _(u'Failed, file is too large')
return HttpResponse(json.dumps(result), status=403,
content_type=content_type)
try: try:
content = uploaded_file.read() content = uploaded_file.read()
encoding = chardet.detect(content)['encoding'] encoding = chardet.detect(content)['encoding']

View File

@@ -1,12 +1,15 @@
import os import os
from tests.api.apitestbase import ApiTestBase import json
from tests.common.utils import urljoin from tests.common.utils import urljoin
from tests.common.common import BASE_URL from tests.common.common import BASE_URL
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from seahub.test_utils import BaseTestCase
from seahub.settings import MEDIA_ROOT, CUSTOM_FAVICON_PATH from seahub.settings import MEDIA_ROOT, CUSTOM_FAVICON_PATH
class AdminFaviconTest(ApiTestBase): class AdminFaviconTest(BaseTestCase):
def setUp(self):
self.login_as(self.admin)
def test_update_favicon(self): def test_update_favicon(self):
@@ -17,18 +20,22 @@ class AdminFaviconTest(ApiTestBase):
assert not os.path.exists(custom_symlink) assert not os.path.exists(custom_symlink)
# update user avatar # update user avatar
logo_url = reverse('api-v2.1-admin-logo') logo_url = reverse('api-v2.1-admin-favicon')
logo_url = urljoin(BASE_URL, logo_url) logo_url = urljoin(BASE_URL, logo_url)
logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png') logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png')
with open(logo_file) as f: with open(logo_file) as f:
json_resp = self.admin_post(logo_url, files={'logo': f}).json() resp = self.client.post(logo_url, {'favicon': f})
assert resp.status_code == 200
json_resp = json.loads(resp.content)
assert json_resp['success'] == True assert json_resp['success'] == True
assert os.path.exists(custom_symlink) assert os.path.exists(custom_symlink)
assert os.path.islink(custom_symlink) assert os.path.islink(custom_symlink)
def test_update_favicon_with_invalid_user_permission(self): def test_update_favicon_with_invalid_user_permission(self):
self.logout()
self.login_as(self.user)
# update user avatar # update user avatar
logo_url = reverse('api-v2.1-admin-favicon') logo_url = reverse('api-v2.1-admin-favicon')
@@ -36,4 +43,19 @@ class AdminFaviconTest(ApiTestBase):
logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png') logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png')
with open(logo_file) as f: with open(logo_file) as f:
json_resp = self.post(logo_url, files={'logo': f}, expected=403).json() resp = self.client.post(logo_url, {'favicon': f})
assert resp.status_code == 403
def test_update_favicon_with_invalid_filetype(self):
with open('test.noico', 'w') as f:
f.write('hello')
logo_url = reverse('api-v2.1-admin-favicon')
logo_url = urljoin(BASE_URL, logo_url)
logo_file = os.path.join(os.getcwd(), 'test.noico')
with open(logo_file) as f:
resp = self.client.post(logo_url, {'favicon': f})
json_resp = json.loads(resp.content)
assert resp.status_code == 400
assert json_resp['error_msg'] == "Filetype not allowed."

View File

@@ -22,8 +22,25 @@ class AdminLicenseTest(BaseTestCase):
url = urljoin(BASE_URL, url) url = urljoin(BASE_URL, url)
with open( with open(
os.path.join(os.getcwd(), 'tests/seahub/utils/seafile-license.txt')) as f: os.path.join(os.getcwd(), 'tests/seahub/utils/seafile-license.txt')) as f:
json_resp = self.client.post(url, {'license': f}) resp = self.client.post(url, {'license': f})
json_resp = json.loads(json_resp.content) json_resp = json.loads(resp.content)
assert json_resp['success'] is True assert json_resp['success'] is True
assert os.path.exists(LICENSE_PATH) assert os.path.exists(LICENSE_PATH)
@patch.object(license_api, 'ccnet_api')
def test_update_license_with_invalid_type(self, mock_ccnet_api):
mock_ccnet_api.return_val = {}
url = reverse('api-v2.1-admin-license')
url = urljoin(BASE_URL, url)
with open('temp.notxt', 'w') as f:
f.write('1')
with open(
os.path.join(os.getcwd(), 'temp.notxt')) as f:
resp = self.client.post(url, {'license': f})
json_resp = json.loads(resp.content)
assert 400 == resp.status_code
assert "Filetype not allowed." == json_resp['error_msg']

View File

@@ -0,0 +1,65 @@
import os
import json
from tests.common.utils import urljoin
from tests.common.common import BASE_URL
from django.core.urlresolvers import reverse
from seahub.test_utils import BaseTestCase
from seahub.settings import MEDIA_ROOT, CUSTOM_LOGO_PATH
class AdminLogoTest(BaseTestCase):
def setUp(self):
self.login_as(self.admin)
def test_update_logo(self):
custom_symlink = os.path.join(MEDIA_ROOT, os.path.dirname(CUSTOM_LOGO_PATH))
if os.path.exists(custom_symlink):
os.remove(custom_symlink)
assert not os.path.exists(custom_symlink)
# update user avatar
image_url = reverse('api-v2.1-admin-login-background-image')
image_url = urljoin(BASE_URL, image_url)
image_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png')
with open(image_file, 'rb') as f:
resp = self.client.post(image_url, {'login_bg_image': f})
json_resp = json.loads(resp.content)
assert 200 == resp.status_code
assert json_resp['success'] == True
assert os.path.exists(custom_symlink)
assert os.path.islink(custom_symlink)
def test_update_logo_with_invalid_user_permission(self):
self.logout()
# update user avatar
image_url = reverse('api-v2.1-admin-login-background-image')
image_url = urljoin(BASE_URL, image_url)
image_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png')
with open(image_file, 'rb') as f:
resp = self.client.post(image_url, {'login_bg_image': f})
assert 403 == resp.status_code
def test_update_logo_with_invalid_file_type(self):
with open('test.noimage', 'w') as f:
f.write('hello')
image_url = reverse('api-v2.1-admin-login-background-image')
image_url = urljoin(BASE_URL, image_url)
image_file = os.path.join(os.getcwd(), 'test.noimage')
with open(image_file, 'rb') as f:
resp = self.client.post(image_url, {'login_bg_image': f})
json_resp = json.loads(resp.content)
os.remove(image_file)
assert 400 == resp.status_code
assert json_resp['error_msg'] == "Filetype not allowed."

View File

@@ -1,12 +1,16 @@
import os import os
from tests.api.apitestbase import ApiTestBase import json
from tests.common.utils import urljoin from tests.common.utils import urljoin
from tests.common.common import BASE_URL from tests.common.common import BASE_URL
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from seahub.test_utils import BaseTestCase
from seahub.settings import MEDIA_ROOT, CUSTOM_LOGO_PATH from seahub.settings import MEDIA_ROOT, CUSTOM_LOGO_PATH
class AdminLogoTest(ApiTestBase):
class AdminLogoTest(BaseTestCase):
def setUp(self):
self.login_as(self.admin)
def test_update_logo(self): def test_update_logo(self):
@@ -21,19 +25,41 @@ class AdminLogoTest(ApiTestBase):
logo_url = urljoin(BASE_URL, logo_url) logo_url = urljoin(BASE_URL, logo_url)
logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png') logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png')
with open(logo_file) as f: with open(logo_file, 'rb') as f:
json_resp = self.admin_post(logo_url, files={'logo': f}).json() resp = self.client.post(logo_url, {'logo': f})
json_resp = json.loads(resp.content)
assert 200 == resp.status_code
assert json_resp['success'] == True assert json_resp['success'] == True
assert os.path.exists(custom_symlink) assert os.path.exists(custom_symlink)
assert os.path.islink(custom_symlink) assert os.path.islink(custom_symlink)
def test_update_logo_with_invalid_user_permission(self): def test_update_logo_with_invalid_user_permission(self):
self.logout()
# update user avatar # update user avatar
logo_url = reverse('api-v2.1-admin-logo') logo_url = reverse('api-v2.1-admin-logo')
logo_url = urljoin(BASE_URL, logo_url) logo_url = urljoin(BASE_URL, logo_url)
logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png') logo_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png')
with open(logo_file) as f: with open(logo_file, 'rb') as f:
json_resp = self.post(logo_url, files={'logo': f}, expected=403).json() resp = self.client.post(logo_url, {'logo': f})
assert 403 == resp.status_code
def test_update_logo_with_invalid_file_type(self):
with open('test.noimage', 'w') as f:
f.write('1')
logo_url = reverse('api-v2.1-admin-logo')
logo_url = urljoin(BASE_URL, logo_url)
logo_file = os.path.join(os.getcwd(), 'test.noimage')
with open(logo_file, 'rb') as f:
resp = self.client.post(logo_url, {'logo': f})
json_resp = json.loads(resp.content)
os.remove(logo_file)
assert 400 == resp.status_code
assert json_resp['error_msg'] == "Filetype not allowed."