[views/zipview] Add security on zip archive download
authorVladimir Popescu <vladimir.popescu@logilab.fr>
Fri, 05 Jul 2013 15:34:34 +0200
changeset 278 9101f6d48451
parent 277 60eba9b3800b
child 279 9eb199a02da8
[views/zipview] Add security on zip archive download Anonymous users are invited to sign in or sign up before being able to download zip archives.
views/zipview.py
--- a/views/zipview.py	Mon Jul 15 15:45:39 2013 +0200
+++ b/views/zipview.py	Fri Jul 05 15:34:34 2013 +0200
@@ -22,7 +22,7 @@
 from contextlib import closing
 from zipfile import ZipFile, ZIP_DEFLATED
 
-from cubicweb.selectors import is_instance
+from cubicweb.predicates import is_instance, authenticated_user, anonymous_user
 from cubicweb.view import EntityView
 
 
@@ -39,7 +39,7 @@
     """
     fd, archive_filepath = tempfile.mkstemp()
     try:
-        noext_archivename = osp.splitext(DataZipView.archive_name)[0]
+        noext_archivename = osp.splitext(DataZipAbstractView.archive_name)[0]
         with closing(ZipFile(archive_filepath, "w", ZIP_DEFLATED)) as zip:
             for filename, subj, filepath in filepaths:
                 zip.write(filepath, '%s/%s/%s' % (noext_archivename, subj, filename))
@@ -51,9 +51,9 @@
         os.unlink(archive_filepath)
         raise
 
-
-class DataZipView(EntityView):
-    """transforms a resultset of acte into a zip archive"""
+class DataZipAbstractView(EntityView):
+    """Abstract base class for the zip view"""
+    __abstract__ = True
     __regid__ = 'data-zip'
     __select__ = EntityView.__select__ & is_instance('Scan', 'GenomicMeasure')
     templatable = False
@@ -63,6 +63,9 @@
     def set_request_content_type(self):
         self._cw.set_content_type('application/zip', filename=self.archive_name)
 
+class DataZipAuthenticatedView(DataZipAbstractView):
+    __select__ = DataZipAbstractView.__select__ & authenticated_user()
+
     def call(self):
         if not self.cw_rset:
             return
@@ -70,16 +73,34 @@
         for entity in self.cw_rset.entities():
             if entity.__regid__ == 'GenomicMeasure':
                 for ext in ('.bim', '.bed', '.fam'):
-                    filepaths.add((entity.filepath.split('/')[-1]+ext, entity.concerns[0].identifier, entity.full_filepath+ext))
+                    filepaths.add((entity.filepath.split('/')[-1]+ext, 
+                                   entity.concerns[0].identifier, 
+                                   entity.full_filepath+ext))
             else:
                 filename = entity.type+'_'+entity.filepath.split('/')[-1]
                 filename = filename.replace(' ', '_')
                 filepaths.add((filename, entity.concerns[0].identifier, entity.full_filepath))
             for external_resource in entity.external_resources:
-                filepaths.add((external_resource.filepath.split('/')[-1], entity.concerns[0].identifier, external_resource.full_filepath))
+                filepaths.add((external_resource.filepath.split('/')[-1], 
+                               entity.concerns[0].identifier, 
+                               external_resource.full_filepath))
         fileobj, archive_filepath = zipfiles(list(filepaths))
         try:
             self.w(fileobj.read())
         finally:
             fileobj.close()
             os.unlink(archive_filepath)
+
+
+class DataZipAnonymousView(DataZipAbstractView):
+    __select__ = DataZipAbstractView.__select__ & anonymous_user()
+    binary = False
+    templatable = True
+
+    def call(self):
+        ahref_login = u'<a href="%s">%s</a>' % (self._cw.build_url('login'), self._cw._('sign in'))
+        ahref_register = u'<a href="%s">%s</a>' % (self._cw.build_url('register'), self._cw._('sign up'))
+        self.w(u'<h2>%s</h2>' 
+               % self._cw._('Please %(login)s or %(register)s before downloading the archive.' 
+                            % {'login': ahref_login, 'register': ahref_register}))
+