Add id and roles to proxy headers and create media on upload

master
esensar 2018-02-03 18:00:56 +01:00
parent 2009ceb5ff
commit 91d02f798e
26 changed files with 128 additions and 107 deletions

View File

@ -2,12 +2,8 @@ package ba.steleks;
/**
* Created by admin on 06/05/2017.
*/
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CrossOriginConfig {

View File

@ -7,7 +7,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpStatusCodeException;
import java.nio.charset.Charset;
import java.util.logging.Logger;
public class CustomHttpStatusException extends HttpStatusCodeException {

View File

@ -0,0 +1,11 @@
package ba.steleks.util;
public final class ProxyHeaders {
private ProxyHeaders() {
// no instance
}
public static final String USER_ID = "X-Proxy-Extra-Id";
public static final String USER_ROLES = "X-Proxy-Extra-Roles";
}

View File

@ -3,7 +3,6 @@ package ba.steleks;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableEurekaServer
@SpringBootApplication

View File

@ -1,10 +1,6 @@
package ba.steleks;
import ba.steleks.model.Event;
import ba.steleks.model.EventTeam;
import ba.steleks.model.EventType;
import ba.steleks.model.Media;
import ba.steleks.storage.StorageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
@ -13,9 +9,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -10,8 +10,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import java.util.logging.Logger;
@Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
@Override

View File

@ -1,23 +1,18 @@
package ba.steleks.controller;
import ba.steleks.service.Service;
import ba.steleks.service.discovery.ServiceDiscoveryClient;
import ba.steleks.error.exception.ExternalServiceException;
import ba.steleks.repository.EventsJpaRepository;
import ba.steleks.model.Event;
import ba.steleks.repository.EventsJpaRepository;
import ba.steleks.util.ProxyHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.ws.rs.GET;
import java.net.URI;
import java.util.Collections;
import java.util.List;
/**
* Created by admin on 01/04/2017.
@ -28,28 +23,15 @@ public class EventController {
private EventsJpaRepository repository;
private RestTemplate restTemplate;
private ServiceDiscoveryClient discoveryClient;
@Autowired
public EventController(EventsJpaRepository repository, RestTemplateBuilder restTemplateBuilder, ServiceDiscoveryClient discoveryClient) {
public EventController(EventsJpaRepository repository) {
this.repository = repository;
this.restTemplate = restTemplateBuilder.build();
this.discoveryClient = discoveryClient;
}
@RequestMapping(path = "/events", method = RequestMethod.POST)
public ResponseEntity<?> add(@RequestBody Event event, @RequestHeader(HttpHeaders.AUTHORIZATION) String token) throws ExternalServiceException {
String usersServiceBase = discoveryClient.getServiceUrl(Service.USERS);
public ResponseEntity<?> add(@RequestBody Event event, @RequestHeader(ProxyHeaders.USER_ID) String userId) throws ExternalServiceException {
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, token);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
restTemplate.exchange(usersServiceBase + "/users/{id}", HttpMethod.GET, entity, String.class, event.getCreatedById());
event.setCreatedById(Long.parseLong(userId));
Event result = repository.save(event);
URI location = ServletUriComponentsBuilder
.fromCurrentRequest().path("/{id}")

View File

@ -4,16 +4,20 @@ import ba.steleks.controller.storage.MediaStorageHandler;
import ba.steleks.error.exception.ExternalServiceException;
import ba.steleks.model.Media;
import ba.steleks.repository.MediaJpaRepository;
import ba.steleks.service.discovery.ServiceDiscoveryClient;
import ba.steleks.storage.StorageService;
import ba.steleks.util.ProxyHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.net.URI;
/**
* Created by admin on 16/04/2017.
@ -23,14 +27,12 @@ public class EventGalleryController {
private final StorageService storageService;
private final MediaJpaRepository repository;
private final ServiceDiscoveryClient discoveryClient;
private final MediaStorageHandler mediaStorageHandler;
@Autowired
public EventGalleryController(StorageService storageService, MediaJpaRepository repository, ServiceDiscoveryClient discoveryClient, MediaStorageHandler mediaStorageHandler) {
public EventGalleryController(StorageService storageService, MediaJpaRepository repository, MediaStorageHandler mediaStorageHandler) {
this.storageService = storageService;
this.repository = repository;
this.discoveryClient=discoveryClient;
this.mediaStorageHandler = mediaStorageHandler;
}
@ -45,25 +47,30 @@ public class EventGalleryController {
.body(file);
}
@PostMapping("/medias/{mediaId}/picture")
public String handleFileUpload(@PathVariable Long mediaId, @RequestParam("file") MultipartFile file,
@PostMapping("/medias/file")
public ResponseEntity<?> handleFileUpload(@RequestParam("file") MultipartFile file,
@RequestHeader(ProxyHeaders.USER_ID) String userId,
RedirectAttributes redirectAttributes) throws ExternalServiceException {
String loadImageEndpoint = mediaStorageHandler.saveMedia(file, mediaId);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
System.out.println(loadImageEndpoint);
Media media = repository.findOne(mediaId);
if(media==null){
media= new Media();
media.setContentUrl(loadImageEndpoint);
media.setCreatedById(0);
repository.save(media);
try {
Media media = new Media();
media.setCreatedById(Long.parseLong(userId));
Media result = repository.save(media);
String url = mediaStorageHandler.saveMedia(file, result.getId());
result.setContentUrl(url);
repository.save(result);
URI location = ServletUriComponentsBuilder
.fromCurrentContextPath().path("/medias/{id}")
.buildAndExpand(result.getId()).toUri();
return ResponseEntity.created(location).body(result);
} catch (Exception ex) {
if (ex instanceof HttpClientErrorException && ((HttpClientErrorException) ex).getStatusCode() == HttpStatus.NOT_FOUND) {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST);
} else {
media.setContentUrl(loadImageEndpoint);
throw new ExternalServiceException();
}
}
repository.save(media);
return "redirect:/";
}
}

View File

@ -1,10 +1,8 @@
package ba.steleks.controller;
import ba.steleks.error.exception.ExternalServiceException;
import ba.steleks.model.Event;
import ba.steleks.model.EventTeam;
import ba.steleks.repository.EventTeamJpaRepository;
import ba.steleks.repository.EventsJpaRepository;
import ba.steleks.service.Service;
import ba.steleks.service.discovery.ServiceDiscoveryClient;
import org.springframework.beans.factory.annotation.Autowired;
@ -12,7 +10,6 @@ import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

View File

@ -6,21 +6,17 @@ import ba.steleks.controller.storage.MediaStorageHandler;
import ba.steleks.error.exception.ExternalServiceException;
import ba.steleks.model.Media;
import ba.steleks.repository.MediaJpaRepository;
import ba.steleks.service.Service;
import ba.steleks.service.discovery.ServiceDiscoveryClient;
import ba.steleks.util.ProxyHeaders;
import org.apache.http.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.imageio.ImageIO;
@ -32,28 +28,23 @@ import java.net.URL;
public class MediaController {
private MediaJpaRepository repository;
private RestTemplate restTemplate;
private ServiceDiscoveryClient discoveryClient;
private MediaStorageHandler mediaStorageHandler;
@Autowired
public MediaController(MediaJpaRepository repository, RestTemplateBuilder restTemplateBuilder, ServiceDiscoveryClient discoveryClient, MediaStorageHandler mediaStorageHandler) {
public MediaController(MediaJpaRepository repository, MediaStorageHandler mediaStorageHandler) {
this.repository = repository;
this.restTemplate = restTemplateBuilder.build();
this.discoveryClient = discoveryClient;
this.mediaStorageHandler = mediaStorageHandler;
}
@RequestMapping(path = "/medias", method = RequestMethod.POST)
public ResponseEntity<?> add(@RequestBody Media media) throws ExternalServiceException {
public ResponseEntity<?> add(@RequestBody Media media, @RequestHeader(ProxyHeaders.USER_ID) String userId) throws ExternalServiceException {
String usersServiceBase = discoveryClient.getServiceUrl(Service.USERS);
try {
// String response = restTemplate.getForObject(usersServiceBase + "/users/{id}", String.class, media.getCreatedById());
BufferedImage mediaImage = null;
if (!TextUtils.isEmpty(media.getContentUrl())) {
mediaImage = ImageIO.read(new URL(media.getContentUrl()));
}
media.setCreatedById(Long.parseLong(userId));
Media result = repository.save(media);
if (mediaImage != null) {

View File

@ -1,5 +1,7 @@
package ba.steleks.model;
import com.sun.istack.internal.Nullable;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Set;
@ -18,6 +20,7 @@ public class Event {
private String longText;
private Timestamp dateTime;
private int duration;
@Nullable
private long createdById;
@ManyToOne

View File

@ -1,7 +1,6 @@
package ba.steleks.model;
import javax.persistence.*;
import java.util.Set;
/**
* Created by admin on 15/04/2017.

View File

@ -1,5 +1,7 @@
package ba.steleks.model;
import com.sun.istack.internal.Nullable;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Date;
@ -18,6 +20,7 @@ public class Media {
private String contentUrl;
@Column(updatable = false, insertable = false)
private Timestamp creationDate;
@Nullable
private long createdById;
public Media() {

View File

@ -35,5 +35,6 @@ dependencies {
compile('org.springframework.cloud:spring-cloud-starter-eureka')
compile('org.springframework.cloud:spring-cloud-starter-zuul')
testCompile('org.springframework.cloud:spring-cloud-starter-eureka-server')
compile project(':common')
}

View File

@ -2,6 +2,7 @@ package ba.steles.security;/**
* Created by ensar on 28/05/17.
*/
import ba.steleks.util.ProxyHeaders;
import ba.steles.service.Service;
import ba.steles.service.discovery.ServiceDiscoveryClient;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@ -16,12 +17,9 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.net.URI;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;
import java.util.*;
import java.util.stream.Collectors;
public class AuthenticationFilter extends GenericFilterBean {
@ -62,6 +60,10 @@ public class AuthenticationFilter extends GenericFilterBean {
.collect(Collectors.toSet());
authentication = new UsernamePasswordAuthenticationToken("a name", null,
roleSet);
ExtraHeadersRequest extraHeadersRequest = new ExtraHeadersRequest((HttpServletRequest) request);
extraHeadersRequest.addExtraHeader(ProxyHeaders.USER_ID, usersResponse.getUserId().toString());
extraHeadersRequest.addExtraHeader(ProxyHeaders.USER_ROLES, userRoleSet);
request = extraHeadersRequest;
} catch (Exception ex) {
ex.printStackTrace();
authentication = null;
@ -73,4 +75,58 @@ public class AuthenticationFilter extends GenericFilterBean {
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
private class ExtraHeadersRequest extends HttpServletRequestWrapper implements HttpServletRequest {
private Map<String, Set<String>> extraHeaders = new HashMap<>();
public ExtraHeadersRequest(HttpServletRequest request) {
super(request);
}
public void addExtraHeader(String name, String value) {
if (!extraHeaders.containsKey(name)) {
extraHeaders.put(name, new HashSet<>());
}
extraHeaders.get(name).add(value);
}
public void addExtraHeader(String name, Collection<String> values) {
if (!extraHeaders.containsKey(name)) {
extraHeaders.put(name, new HashSet<>());
}
extraHeaders.get(name).addAll(values);
}
@Override
public Enumeration<String> getHeaders(String name) {
List<String> allHeaders = new ArrayList<>(Collections.list(super.getHeaders(name)));
if (extraHeaders.containsKey(name)) {
allHeaders.addAll(extraHeaders.get(name));
}
return Collections.enumeration(allHeaders);
}
@Override
public Enumeration<String> getHeaderNames() {
List<String> allHeaders = new ArrayList<>(Collections.list(super.getHeaderNames()));
allHeaders.addAll(extraHeaders.keySet());
return Collections.enumeration(allHeaders);
}
@Override
public String getHeader(String name) {
String header = super.getHeader(name);
if (header == null) {
Set<String> headers = extraHeaders.get(name);
if (headers == null || headers.isEmpty()) {
return null;
} else {
return Collections.enumeration(headers).nextElement();
}
} else {
return header;
}
}
}
}

View File

@ -7,7 +7,6 @@ import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.logging.Logger;
@Component
public class RelayTokenFilter extends ZuulFilter {

View File

@ -5,17 +5,13 @@ package ba.steles.security;/**
import ba.steles.service.discovery.ServiceDiscoveryClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.client.RestTemplate;
@Configuration
@EnableWebSecurity

View File

@ -7,8 +7,6 @@ import ba.steleks.service.Service;
import ba.steleks.service.discovery.ServiceDiscoveryClient;
import ba.steleks.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
@ -17,7 +15,6 @@ import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.Date;
import java.util.List;
/**
* Created by admin on 16/04/2017.

View File

@ -1,6 +1,9 @@
package ba.steleks.model;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
* Created by admin on 23/03/2017.

View File

@ -2,17 +2,14 @@ package ba.steleks;
import ba.steleks.storage.StorageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

View File

@ -3,7 +3,6 @@ package ba.steleks.controller;
import ba.steleks.error.exception.CustomHttpStatusException;
import ba.steleks.model.AuthRequest;
import ba.steleks.model.User;
import ba.steleks.model.UserRole;
import ba.steleks.repository.UsersJpaRepository;
import ba.steleks.security.SessionIdentifierGenerator;
import ba.steleks.security.UserRoleFactory;
@ -11,7 +10,6 @@ import ba.steleks.security.token.TokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

View File

@ -7,12 +7,13 @@ import ba.steleks.service.Service;
import ba.steleks.service.discovery.ServiceDiscoveryClient;
import ba.steleks.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.core.io.Resource;
import java.util.Date;
/**

View File

@ -10,7 +10,6 @@ import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Set;
import java.util.logging.Logger;
@Entity
@EntityListeners(UserPasswordEntityListener.class)

View File

@ -4,7 +4,6 @@ package ba.steleks.security;/**
import ba.steleks.repository.UsersJpaRepository;
import ba.steleks.security.token.TokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

View File

@ -7,7 +7,6 @@ package ba.steleks.security;
import ba.steleks.repository.UsersJpaRepository;
import ba.steleks.security.token.TokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;

View File

@ -4,10 +4,8 @@ import ba.steleks.AutowireHelper;
import ba.steleks.model.User;
import ba.steleks.repository.UserRolesJpaRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import javax.persistence.PostPersist;
import javax.persistence.PrePersist;