source: trunk/grails-app/controllers/nl/tno/metagenomics/files/FileController.groovy @ 27

Last change on this file since 27 was 27, checked in by robert@…, 8 years ago

Renamed module to massSequencing

File size: 5.9 KB
Line 
1/**
2 * FileController
3 *
4 * Handles file uploads and downloads
5 *
6 * @author      Robert Horlings
7 * @since       20100601
8 * @package     dbnp.studycapturing
9 *
10 * Revision information:
11 * $Rev: 1182 $
12 * $Author: robert@isdat.nl $
13 * $Date: 2010-11-22 17:27:23 +0100 (Mon, 22 Nov 2010) $
14 */
15package nl.tno.massSequencing.files
16
17import nl.tno.massSequencing.*;
18
19import org.codehaus.groovy.grails.commons.ConfigurationHolder
20import org.springframework.web.multipart.MultipartHttpServletRequest
21import grails.converters.*
22import org.apache.commons.io.IOUtils;
23
24class FileController {
25
26        def fileService;
27
28        /**
29         * Returns the file that is asked for from the temporary upload directory
30         * or a 404 error if the file doesn't exist
31         */
32        def get = {
33                // Remove all old files from the upload directory, so the user
34                // can't retrieve any old file that were left behind
35                fileService.cleanDirectory();
36               
37                retrieveFile( params, fileService.getUploadDir() );
38        }
39
40        /**
41         * Deletes the file that is asked for from the temporary upload directory
42         * or a 404 error if the file doesn't exist
43         */
44        def delete = {
45                File directory = fileService.getUploadDir()
46                String filename = checkFile( params, directory );
47               
48                response.contentType = "text/plain"
49               
50                try {
51                        fileService.delete( filename, directory );
52                        render ''
53                } catch( Exception e ) {
54                        response.status = 500;
55                        render e.getMessage();
56                }
57        }
58
59        /**
60         * Returns the file that is asked for from the temporary upload directory
61         * or a 404 error if the file doesn't exist
62         */
63        def getPermanent  = {
64                if( checkPermissions( params, fileService.absolutePath( ConfigurationHolder.config.massSequencing.fileDir ) ) ) {
65                        retrieveFile( params, fileService.absolutePath( ConfigurationHolder.config.massSequencing.fileDir ) );
66                } else {
67                        render 'No access';
68                }
69        }
70       
71        /**
72         * Checks whether the user is allowed to access this file. He is only allowed to
73         * if he has access to the study this file belongs to.
74         *
75         * The file could be pointed to in several locations:
76         *   - SequenceData.sequenceFile
77         *   - SequenceData.qualityFile
78         *   - Run.parameterFile
79         *   
80         * If the file is not mentioned in any of these locations, it should not be returned by this system and
81         * a 404 error is given. If the user doesn't have access to the file, a 403 is given.
82         *
83         * @param params        HTTP request parameters
84         * @param directory     File object representing the directory to search in
85         */
86        private boolean checkPermissions( params, directory ) {
87                String filename = checkFile( params, directory );
88               
89                if( !filename )
90                        return;
91               
92                // Search for the file in the sequenceData file fields
93                def sd = SequenceData.findBySequenceFileOrQualityFile( filename, filename );
94                if( sd ) {
95                        if( sd.sample?.sample?.study?.canRead( session.user ) ) {
96                                return true;
97                        } else {
98                                response.setStatus( 403, "Not authorized to access this file" );
99                                return false;
100                        }
101                }
102               
103                // Search for the file in run file fields. If the file is found in that spot
104                // it is freely accessible by any logged in user
105                def run = Run.findByParameterFile( filename );
106                if( run ) {
107                        if( session.user ) {
108                                return true;
109                        } else {
110                                response.setStatus( 403, "Not authorized to access this file" );
111                                return false;
112                        }
113                }
114               
115                // Otherwise, the file should not be accessed this way
116                response.setStatus( 404, "File not found" );
117                return false;
118        }
119
120        private void retrieveFile( params, directory ) {
121                String filename = checkFile( params, directory );
122                def file = fileService.get( filename, directory );
123
124                //response.setContentType("application/octet-stream")
125                //response.setContentType( "image/jpeg" );
126
127                // Return the file
128                response.setHeader "Content-disposition", "attachment; filename=${filename}"
129                response.outputStream << file.newInputStream()
130                response.outputStream.flush()
131        }
132
133        private String checkFile( params, directory ) {
134                def fileExists;
135
136                // Filename is not url decoded for some reason
137                def coder = new org.apache.commons.codec.net.URLCodec()
138                def filename = coder.decode(params.id)
139
140                if( !filename ) {
141                        response.contentType = "text/plain"
142                        response.status = 404;
143                        render( "File not found" );
144                        return;
145                }
146
147                // Security check to prevent accessing files in other directories
148                if( filename.contains( '..' ) ) {
149                        response.contentType = "text/plain"
150                        response.status = 500;
151                        render "Invalid filename given";
152                        return;
153                }
154
155                try {
156                        fileExists = fileService.fileExists( filename, directory )
157                } catch( FileNotFoundException e ) {
158                        fileExists = false;
159                }
160                if( !filename || !fileExists ) {
161                        response.contentType = "text/plain"
162                        response.status = 404;
163                        render( "File not found" );
164                        return;
165                }
166               
167                return filename;
168        }
169
170        /**
171         * Uploads a file and returns the filename under which the file is saved
172         */
173        def upload = {
174                // If an old file exists, delete it
175                if( params.get( 'oldFile' ) ) {
176                        fileService.delete( params.get( 'oldFile' ) );
177                }
178
179                render moveUploadedFile( fileService. getUploadDir() ) as JSON
180        }
181
182        protected def moveUploadedFile(File absolutePath ) {
183                if( !( request instanceof MultipartHttpServletRequest ) ) {
184                        response.setStatus( response.SC_BAD_REQUEST );
185                        log.error( "Request for file upload is not multipart: " + params );
186                        return [];
187                }
188               
189                MultipartHttpServletRequest mpr = (MultipartHttpServletRequest) request;
190                def uploadedFile = mpr.getFile( 'Filedata' )
191               
192                String filename = uploadedFile.getOriginalFilename();
193
194                // URL decode the filename
195                def coder = new org.apache.commons.codec.net.URLCodec()
196                filename = coder.decode(filename)
197
198                String newFilename = fileService.getUniqueFilename( filename, absolutePath );
199                try {
200                        uploadedFile.transferTo( new File( absolutePath, newFilename ) );
201
202                        response.setStatus(response.SC_OK);
203                       
204                        return [ 'success': true, 'filename': newFilename ]
205                } catch (Exception ex) {
206                        log.error( "Fileupload has thrown an exception: " + ex.getMessage());
207
208                        response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
209                        return [ 'success': false ]
210                }
211        }
212
213
214}
Note: See TracBrowser for help on using the repository browser.