1919from django import forms
2020from django .shortcuts import render , redirect , get_object_or_404
2121from django .http import HttpResponse , HttpResponseRedirect , HttpResponseForbidden , Http404
22+ from django .conf import settings
2223from django .contrib import messages
2324from django .contrib .auth .decorators import login_required
2425from django .urls import reverse ,reverse_lazy
2526from django .db .models import Min , Max , Q
26- from django .conf import settings
2727from django .forms .models import modelform_factory , inlineformset_factory
2828from django .forms import ModelForm
2929from django .template import TemplateDoesNotExist
3333from django .utils .text import slugify
3434from django .views .decorators .csrf import ensure_csrf_cookie , csrf_exempt
3535from django .views .generic import RedirectView
36- from django . template . defaultfilters import filesizeformat
36+
3737
3838from ietf .doc .fields import SearchableDocumentsField
3939from ietf .doc .models import Document , State , DocEvent , NewRevisionDocEvent
6464from ietf .utils .pipe import pipe
6565from ietf .utils .pdf import pdf_pages
6666from ietf .utils .text import xslugify
67+ from ietf .utils .textupload import ( validate_file_size , validate_mime_type ,
68+ validate_file_extension , validate_no_html_frame , )
6769
6870from .forms import (InterimMeetingModelForm , InterimAnnounceForm , InterimSessionModelForm ,
6971 InterimCancelForm , InterimSessionInlineFormSet )
@@ -1132,6 +1134,12 @@ def add_session_drafts(request, session_id, num):
11321134class UploadBlueSheetForm (forms .Form ):
11331135 file = forms .FileField (label = 'Bluesheet scan to upload' )
11341136
1137+ def clean_file (self ):
1138+ file = self .cleaned_data ['file' ]
1139+ validate_mime_type (file .read (), settings .MEETING_VALID_BLUESHEET_MIME_TYPES )
1140+ validate_file_extension (file .name , settings .MEETING_VALID_BLUESHEET_EXTENSIONS )
1141+ return file
1142+
11351143@role_required ('Area Director' , 'Secretariat' , 'IRTF Chair' , 'WG Chair' )
11361144def upload_session_bluesheets (request , session_id , num ):
11371145 # num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
@@ -1196,7 +1204,7 @@ def upload_session_bluesheets(request, session_id, num):
11961204 'form' : form ,
11971205 })
11981206
1199- VALID_MINUTES_EXTENSIONS = ( '.txt' , '.html' , '.htm' , '.pdf' )
1207+
12001208# FIXME: This form validation code (based on the secretariat upload code) only looks at filename extensions
12011209# It should look at the contents of the files instead.
12021210class UploadMinutesForm (forms .Form ):
@@ -1210,10 +1218,12 @@ def __init__(self, show_apply_to_all_checkbox, *args, **kwargs):
12101218
12111219 def clean_file (self ):
12121220 file = self .cleaned_data ['file' ]
1213- if file ._size > settings .SECR_MAX_UPLOAD_SIZE :
1214- raise forms .ValidationError ('Please keep filesize under %s. Requested upload size is %s' % (filesizeformat (settings .SECR_MAX_UPLOAD_SIZE ),filesizeformat (file ._size )))
1215- if os .path .splitext (file .name )[1 ].lower () not in VALID_MINUTES_EXTENSIONS :
1216- raise forms .ValidationError ('Only these file types supported for minutes: %s' % ',' .join (VALID_MINUTES_EXTENSIONS ))
1221+ validate_file_size (file ._size )
1222+ ext = validate_file_extension (file .name , settings .MEETING_VALID_MINUTES_EXTENSIONS )
1223+ content = file .read ()
1224+ mime_type , encoding = validate_mime_type (content , settings .MEETING_VALID_MINUTES_MIME_TYPES )
1225+ if ext in ['.html' , '.htm' ] or mime_type in ['text/html' , ]:
1226+ validate_no_html_frame (content )
12171227 return file
12181228
12191229def upload_session_minutes (request , session_id , num ):
@@ -1292,7 +1302,7 @@ def upload_session_minutes(request, session_id, num):
12921302 'form' : form ,
12931303 })
12941304
1295- VALID_AGENDA_EXTENSIONS = ( '.txt' , '.html' , '.htm' ,)
1305+
12961306# FIXME: This form validation code (based on the secretariat upload code) only looks at filename extensions
12971307# It should look at the contents of the files instead.
12981308class UploadAgendaForm (forms .Form ):
@@ -1306,10 +1316,12 @@ def __init__(self, show_apply_to_all_checkbox, *args, **kwargs):
13061316
13071317 def clean_file (self ):
13081318 file = self .cleaned_data ['file' ]
1309- if file ._size > settings .SECR_MAX_UPLOAD_SIZE :
1310- raise forms .ValidationError ('Please keep filesize under %s. Requested upload size is %s' % (filesizeformat (settings .SECR_MAX_UPLOAD_SIZE ),filesizeformat (file ._size )))
1311- if os .path .splitext (file .name )[1 ].lower () not in VALID_AGENDA_EXTENSIONS :
1312- raise forms .ValidationError ('Only these file types supported for agendas: %s' % ',' .join (VALID_AGENDA_EXTENSIONS ))
1319+ validate_file_size (file ._size )
1320+ ext = validate_file_extension (file .name , settings .MEETING_VALID_AGENDA_EXTENSIONS )
1321+ content = file .read ()
1322+ mime_type , encoding = validate_mime_type (content , settings .MEETING_VALID_AGENDA_MIME_TYPES )
1323+ if ext in ['.html' , '.htm' ] or mime_type in ['text/html' , ]:
1324+ validate_no_html_frame (content )
13131325 return file
13141326
13151327def upload_session_agenda (request , session_id , num ):
@@ -1400,7 +1412,7 @@ def upload_session_agenda(request, session_id, num):
14001412 'form' : form ,
14011413 })
14021414
1403- VALID_SLIDE_EXTENSIONS = ( '.doc' , '.docx' , '.pdf' , '.ppt' , '.pptx' , '.txt' ) # Note the removal of .zip
1415+
14041416# FIXME: This form validation code (based on the secretariat upload code) only looks at filename extensions
14051417# It should look at the contents of the files instead.
14061418class UploadSlidesForm (forms .Form ):
@@ -1415,10 +1427,8 @@ def __init__(self, show_apply_to_all_checkbox, *args, **kwargs):
14151427
14161428 def clean_file (self ):
14171429 file = self .cleaned_data ['file' ]
1418- if file ._size > settings .SECR_MAX_UPLOAD_SIZE :
1419- raise forms .ValidationError ('Please keep filesize under %s. Requested upload size is %s' % (filesizeformat (settings .SECR_MAX_UPLOAD_SIZE ),filesizeformat (file ._size )))
1420- if os .path .splitext (file .name )[1 ].lower () not in VALID_SLIDE_EXTENSIONS :
1421- raise forms .ValidationError ('Only these file types supported for slides: %s' % ',' .join (VALID_SLIDE_EXTENSIONS ))
1430+ validate_file_size (file ._size )
1431+ validate_file_extension (file .name , settings .MEETING_VALID_SLIDES_EXTENSIONS )
14221432 return file
14231433
14241434def upload_session_slides (request , session_id , num , name ):
0 commit comments