Skip to content
Snippets Groups Projects
Commit a0a20889 authored by Thomas's avatar Thomas
Browse files

Added file upload/download

parent eed646c6
No related branches found
No related tags found
No related merge requests found
package mozen.auth;
import java.util.Arrays;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
......@@ -8,6 +12,9 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter{
......@@ -35,4 +42,20 @@ public class WebSecurity extends WebSecurityConfigurerAdapter{
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.unmodifiableList(Arrays.asList("*")));
configuration.setAllowedMethods(Collections.unmodifiableList(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH")));
// setAllowCredentials(true) is important, otherwise:
// The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// setAllowedHeaders is important! Without it, OPTIONS preflight request
// will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(Collections.unmodifiableList(Arrays.asList("Authorization", "Cache-Control", "Content-Type")));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package mozen.business;
import java.util.Collection;
import mozen.model.CustomLayer;
import mozen.model.Model;
import mozen.model.TagCategory;
......@@ -10,8 +11,14 @@ public interface IModelDao {
void updateModel(Model m);
void removeModel(long id);
void addLayer(CustomLayer l);
void updateLayer(CustomLayer l);
void removeLayer(long id);
Collection<TagCategory> getTags();
Model findModel(long id);
Collection<Model> findModelsByName(String name);
CustomLayer findLayer(long id);
}
\ No newline at end of file
......@@ -2,15 +2,26 @@ package mozen.business;
import java.util.Collection;
import org.springframework.web.multipart.MultipartFile;
import mozen.model.CustomLayer;
import mozen.model.Model;
import mozen.model.TagCategory;
import mozen.model.User;
public interface IModelManager {
Long addModel(Model m);
void updateModel(Model m);
void removeModel(Long id);
Long addModel(Model m, User user) throws Exception;
void updateModel(Model m, long id, User user) throws Exception;
void removeModel(long id, User user) throws Exception;
Long addLayer(long modelId, CustomLayer layer, User user) throws Exception;
void updateLayer(long id, CustomLayer layer, User user) throws Exception;
void removeLayer(long id, User user) throws Exception;
void addFile(MultipartFile file, long id, User user) throws Exception;
void addLayerFile(MultipartFile file, long id, User user) throws Exception;
Model getModel(Long id);
Model getModel(long id);
Collection<TagCategory> getTags();
Collection<Model> findModel(String name);
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import mozen.model.CustomLayer;
import mozen.model.Model;
import mozen.model.TagCategory;
......@@ -33,8 +34,7 @@ public class ModelDao implements IModelDao {
@Override
public void removeModel(long id) {
Model m = findModel(id);
em.remove(m);
em.remove(findModel(id));
}
@Override
......@@ -65,4 +65,24 @@ public class ModelDao implements IModelDao {
}
}
@Override
public void addLayer(CustomLayer l) {
em.persist(l);
}
@Override
public void updateLayer(CustomLayer l) {
em.merge(l);
}
@Override
public void removeLayer(long id) {
em.remove(findLayer(id));
}
@Override
public CustomLayer findLayer(long id) {
return em.find(CustomLayer.class, id);
}
}
\ No newline at end of file
......@@ -4,9 +4,12 @@ import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import mozen.model.CustomLayer;
import mozen.model.Model;
import mozen.model.TagCategory;
import mozen.model.User;
@Service
public class ModelManager implements IModelManager {
......@@ -15,23 +18,42 @@ public class ModelManager implements IModelManager {
IModelDao dao;
@Override
public Long addModel(Model m) {
dao.addModel(m);
return m.getId();
public Long addModel(Model model, User user) throws Exception {
model.setAuthor(user);
dao.addModel(model);
return model.getId();
}
@Override
public void updateModel(Model m) {
dao.updateModel(m);
public void addFile(MultipartFile file, long id, User user) throws Exception {
Model model = dao.findModel(id);
if (model == null) throw new Exception("Unknown model");
model.setFile(file.getBytes());
model.setFileType(file.getContentType());
dao.updateModel(model);
}
@Override
public void removeModel(Long id) {
public void updateModel(Model model, long id, User user) throws Exception {
Model modelToUpdate = dao.findModel(id);
if (modelToUpdate == null) throw new Exception("Unknown model");
if(!isModelAuthor(modelToUpdate, user)) throw new Exception("Not the author");
model.setId(id);
dao.updateModel(model);
}
@Override
public void removeModel(long id, User user) throws Exception {
Model model = dao.findModel(id);
if (model == null) throw new Exception("Unknown model");
if(!isModelAuthor(model, user)) throw new Exception("Not the author");
dao.removeModel(id);
}
@Override
public Model getModel(Long id) {
public Model getModel(long id) {
return dao.findModel(id);
}
......@@ -47,4 +69,53 @@ public class ModelManager implements IModelManager {
return dao.getTags();
}
@Override
public Long addLayer(long modelId, CustomLayer layer, User user) throws Exception {
Model model = dao.findModel(modelId);
if (model == null) throw new Exception("Unknown model");
if(!isModelAuthor(model, user)) throw new Exception("Not the author");
layer.setModel(model);
dao.addLayer(layer);
return layer.getId();
}
@Override
public void updateLayer(long id, CustomLayer layer, User user) throws Exception {
CustomLayer layerToUpdate = dao.findLayer(id);
if (layerToUpdate == null) throw new Exception("Unknown layer");
if(!isLayerAuthor(layerToUpdate, user)) throw new Exception("Not the author");
layer.setId(id);
dao.updateLayer(layer);
}
@Override
public void removeLayer(long id, User user) throws Exception {
CustomLayer layer = dao.findLayer(id);
if (layer == null) throw new Exception("Unknown layer");
if(!isLayerAuthor(layer, user)) throw new Exception("Not the author");
dao.removeLayer(id);
}
@Override
public void addLayerFile(MultipartFile file, long id, User user) throws Exception {
CustomLayer layer = dao.findLayer(id);
if (layer == null) throw new Exception("Unknown layer");
if(!isLayerAuthor(layer, user)) throw new Exception("Not the author");
layer.setFile(file.getBytes());
dao.updateLayer(layer);
}
private boolean isLayerAuthor(CustomLayer layer, User user) {
return layer.getModel().getAuthor() == user;
}
private boolean isModelAuthor(Model model, User user) {
return model.getAuthor() == user;
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
......@@ -24,17 +25,13 @@ public class CustomLayer implements Serializable{
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic
@Column(nullable = false)
private Long localID;
@Basic
@Column(nullable = false)
private String name;
@Basic
@Lob
@Column
private String filePath;
private byte[] file;
@Basic
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
......@@ -43,11 +40,10 @@ public class CustomLayer implements Serializable{
public CustomLayer() {
}
public CustomLayer(Long id, Long localID, String name, String filePath, Model model) {
public CustomLayer(Long id, String name, byte[] file, Model model) {
this.id = id;
this.localID = localID;
this.name = name;
this.filePath = filePath;
this.file = file;
this.model = model;
}
......@@ -59,14 +55,6 @@ public class CustomLayer implements Serializable{
this.id = id;
}
public Long getLocalID() {
return this.localID;
}
public void setLocalID(Long localID) {
this.localID = localID;
}
public String getName() {
return this.name;
}
......@@ -76,12 +64,12 @@ public class CustomLayer implements Serializable{
}
@JsonIgnore
public String getFilePath() {
return this.filePath;
public byte[] getFile() {
return this.file;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
public void setFile(byte[] file) {
this.file = file;
}
@JsonIgnore
......
......@@ -12,6 +12,7 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
......@@ -62,9 +63,13 @@ public class Model implements Serializable{
@Column
private int votes;
@Lob
@Column
private byte[] file;
@Basic
@Column
private String filePath;
private String fileType;
@Basic
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
......@@ -83,7 +88,7 @@ public class Model implements Serializable{
public Model() {
}
public Model(Long id, String name, String shortDescription, String longDescription, String added, String lastModified, int votes, String filePath, User author, Set<Tag> tags, Set<CustomLayer> customLayers) {
public Model(Long id, String name, String shortDescription, String longDescription, String added, String lastModified, int votes, byte[] file, String fileType, User author, Set<Tag> tags, Set<CustomLayer> customLayers) {
this.id = id;
this.name = name;
this.shortDescription = shortDescription;
......@@ -91,7 +96,8 @@ public class Model implements Serializable{
this.added = added;
this.lastModified = lastModified;
this.votes = votes;
this.filePath = filePath;
this.file = file;
this.fileType = fileType;
this.author = author;
this.tags = tags;
this.customLayers = customLayers;
......@@ -154,12 +160,12 @@ public class Model implements Serializable{
}
@JsonIgnore
public String getFilePath() {
return this.filePath;
public byte[] getFile() {
return this.file;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
public void setFile(byte[] file) {
this.file = file;
}
public User getAuthor() {
......@@ -186,4 +192,12 @@ public class Model implements Serializable{
this.customLayers = customLayers;
}
public String getFileType() {
return this.fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
}
\ No newline at end of file
......@@ -75,11 +75,9 @@ public class DatabaseFiller {
Set<CustomLayer> m1layers = new HashSet<CustomLayer>();
CustomLayer l1 = new CustomLayer();
l1.setName("super layer 1");
l1.setLocalID((long) 1);
CustomLayer l2 = new CustomLayer();
l2.setName("super layer 2");
l2.setLocalID((long) 2);
m1layers.add(l1);
m1layers.add(l2);
......
......@@ -3,20 +3,30 @@ package mozen.web;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import mozen.business.IModelManager;
import mozen.business.IUserManager;
import mozen.model.Model;
import mozen.model.ResponseMessage;
import mozen.model.TagCategory;
import mozen.model.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
......@@ -32,39 +42,126 @@ public class ModelController {
IUserManager userManager;
@GetMapping("")
public ResponseEntity<?> getUserModels(@RequestParam(value = "id", required = false) Long id) {
if(id != null) {
// User u = userManager.getUser(id);
// return ResponseEntity.ok().body(u.getModels());
public ResponseEntity<?> getModelDetails(@RequestParam(value = "id", required = false) Long id) {
User user = getUser();
if(user != null) {
return ResponseEntity.ok().body(user.getModels());
} else {
return ResponseEntity.ok().body(modelManager.getModel(id));
}
return null;
}
@PostMapping("")
public ResponseEntity<ResponseMessage> addModel(Model model) {
ResponseMessage response = new ResponseMessage(false, "");
User user = getUser();
if(user == null) {
response.setError(true);
response.setMessage("User unknown");
return ResponseEntity.ok(response);
}
try {
modelManager.addModel(model);
modelManager.addModel(model, user);
} catch (Exception e) {
response.setError(true);
response.setMessage("nah");
response.setMessage(e.getMessage());
}
return ResponseEntity.ok(response);
}
@PutMapping("")
public ResponseEntity<ResponseMessage> updateModel(@RequestParam(value = "id", required = true) Long id, Model model) {
ResponseMessage response = new ResponseMessage(false, "");
User user = getUser();
if(user == null) {
response.setError(true);
response.setMessage("User unknown");
return ResponseEntity.ok(response);
}
try {
modelManager.updateModel(model, id, user);
} catch (Exception e) {
response.setError(true);
response.setMessage(e.getMessage());
}
return ResponseEntity.ok(response);
}
@DeleteMapping("")
public ResponseEntity<?> deleteModel(@RequestParam(value = "id", required = true) Long id) {
modelManager.removeModel(id);
return ResponseEntity.ok(null);
public ResponseEntity<ResponseMessage> deleteModel(@RequestParam(value = "id", required = true) Long id) {
ResponseMessage response = new ResponseMessage(false, "");
User user = getUser();
if(user == null) {
response.setError(true);
response.setMessage("User unknown");
return ResponseEntity.ok(response);
}
try {
modelManager.removeModel(id, user);
} catch (Exception e) {
response.setError(true);
response.setMessage(e.getMessage());
}
return ResponseEntity.ok(response);
}
@GetMapping("/tags")
public Collection<TagCategory> getTags() {
return modelManager.getTags();
}
@PostMapping("/upload")
public ResponseEntity<ResponseMessage> uploadModelFile(@RequestParam(value = "id", required = true) Long id, @RequestParam("file") MultipartFile file) {
ResponseMessage response = new ResponseMessage(false, "");
User user = getUser();
if(user == null) {
response.setError(true);
response.setMessage("User unknown");
return ResponseEntity.ok(response);
}
try {
modelManager.addFile(file, id, user);
} catch (Exception e) {
response.setError(true);
response.setMessage(e.getMessage());
}
return ResponseEntity.ok(response);
}
@PostMapping("/download")
public ResponseEntity<?> downloadModelFile(@RequestParam(value = "id", required = true) Long id) {
ResponseMessage response = new ResponseMessage(false, "");
try {
Model model = modelManager.getModel(id);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(model.getFileType()))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + model.getName() + "\"")
.body(new ByteArrayResource(model.getFile()));
} catch (Exception e) {
response.setError(true);
response.setMessage(e.getMessage());
}
return ResponseEntity.ok(response);
}
private User getUser() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetails = (UserDetails) auth.getPrincipal();
return userManager.getUserByUsername(userDetails.getUsername());
} else {
return null;
}
}
}
\ No newline at end of file
......@@ -4,6 +4,8 @@ import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -26,7 +28,8 @@ public class UserController {
@GetMapping("")
public User getUser() {
return new User();
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return manager.getUserByUsername(userDetails.getUsername());
}
@PostMapping("/signup")
......@@ -36,5 +39,4 @@ public class UserController {
ResponseMessage response = new ResponseMessage(false, "");
return ResponseEntity.ok(response);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment