Newer
Older
package it.inaf.ia2.transfer.controller;
import it.inaf.ia2.transfer.auth.GmsClient;
import it.inaf.ia2.transfer.auth.TokenPrincipal;
import it.inaf.ia2.transfer.persistence.FileDAO;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GetFileController {
private static final Logger LOG = LoggerFactory.getLogger(GetFileController.class);
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
@Value("${path_prefix}")
String pathPrefix;
@Autowired
private FileDAO fileDAO;
@Autowired
private GmsClient gmsClient;
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@GetMapping("/**")
public ResponseEntity<?> getFile() {
String path = request.getServletPath();
Optional<FileInfo> optFileInfo = fileDAO.getFileInfo(path);
if (optFileInfo.isPresent()) {
FileInfo fileInfo = optFileInfo.get();
if (!fileInfo.isIsPublic() && !privateButDownloadable(fileInfo)) {
return new ResponseEntity<>("Unauthorized", UNAUTHORIZED);
}
return getFileResponse(fileInfo);
} else {
return new ResponseEntity<>("File " + path + " not found", NOT_FOUND);
}
}
private boolean privateButDownloadable(FileInfo fileInfo) {
String token = ((TokenPrincipal) request.getUserPrincipal()).getToken();
if (token == null) {
return false;
}
// TODO: configure cache
if (fileInfo.getGroupRead() == null) {
return false;
}
for (String group : fileInfo.getGroupRead()) {
if (gmsClient.isMemberOf(token, group)) {
return true;
}
}
return false;
}
private ResponseEntity<?> getFileResponse(FileInfo fileInfo) {
String path = pathPrefix + fileInfo.getOsRelPath();
if (fileInfo.isAsyncTrans()) {
// TODO: add /retrieve part
}
File file = new File(path);
if (!file.exists()) {
return new ResponseEntity<>("File " + file.getName() + " not found", NOT_FOUND);
}
if (!file.canRead()) {
return new ResponseEntity<>("File " + file.getName() + " is not readable", INTERNAL_SERVER_ERROR);
}
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
response.setHeader("Content-Length", String.valueOf(file.length()));
byte[] bytes = new byte[1024];
try ( OutputStream out = response.getOutputStream(); InputStream is = new FileInputStream(file)) {
int read;
while ((read = is.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return null;
}
}