Skip to content

Commit 9e9a8e2

Browse files
committed
added api for downloading files and updated naming conventions for some files
1 parent 8dd30a4 commit 9e9a8e2

File tree

12 files changed

+74
-19
lines changed

12 files changed

+74
-19
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ target/**
7676
jukebox.iml
7777
mvnw
7878
mvnw.cmd
79+
uploads/

src/main/java/com/innoventes/jukebox/advice/RestExceptionHandler.java

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.springframework.http.ResponseEntity;
1313
import org.springframework.web.bind.annotation.ControllerAdvice;
1414
import org.springframework.web.bind.annotation.ExceptionHandler;
15+
import org.springframework.web.multipart.MaxUploadSizeExceededException;
1516

1617
@Order(Ordered.HIGHEST_PRECEDENCE)
1718
@ControllerAdvice
@@ -37,4 +38,9 @@ public ResponseEntity<JukeboxResponse> handleInternalServerException(JukeBoxInte
3738
public ResponseEntity<JukeboxResponse> handleNotFoundException(JukeboxNotFoundException exception){
3839
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(exception.getMessage()));
3940
}
41+
42+
@ExceptionHandler(value = {MaxUploadSizeExceededException.class})
43+
public ResponseEntity<JukeboxResponse> handleMaxUploadExceededException(MaxUploadSizeExceededException exception){
44+
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ErrorResponse("File size is too large!"));
45+
}
4046
}

src/main/java/com/innoventes/jukebox/constants/ApiConstants.java

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public class ApiConstants {
2020

2121
public static final String API_ENCRYPT = BASE_URL + "/auth/encrypt/{var}";
2222

23+
public static final String DOWNLOAD_FILE_BASE_PATH = "/downloadFile/";
24+
25+
public static final String API_DOWNLOAD_FILE = BASE_URL + DOWNLOAD_FILE_BASE_PATH + "{fileName}";
26+
2327
public static final String ALBUM_BASE_PATH = BASE_URL + "/album";
2428

2529
public static final String API_ALBUM_SORT_BY_PRICE = BASE_URL + "/album/sort/price";
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,44 @@
11
package com.innoventes.jukebox.controller;
22

33
import com.innoventes.jukebox.constants.SwaggerConstants;
4-
import com.innoventes.jukebox.controller.helper.AuthHelper;
4+
import com.innoventes.jukebox.controller.helper.PublicHelper;
55
import com.innoventes.jukebox.models.request.LoginRequest;
66
import com.innoventes.jukebox.models.response.JukeboxResponse;
77
import com.innoventes.jukebox.models.response.SuccessResponse;
88
import io.swagger.annotations.Api;
99
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.core.io.Resource;
1011
import org.springframework.http.ResponseEntity;
1112
import org.springframework.security.crypto.password.PasswordEncoder;
1213
import org.springframework.web.bind.annotation.*;
1314

15+
import javax.servlet.http.HttpServletRequest;
16+
1417
import static com.innoventes.jukebox.constants.ApiConstants.*;
1518

1619
@RestController
1720
@Api(tags = {SwaggerConstants.AUTHENTICATION_MANAGEMENT})
18-
public class AuthController {
21+
public class PublicController {
1922

2023
@Autowired
21-
private AuthHelper authHelper;
24+
private PublicHelper publicHelper;
2225

2326
@Autowired
2427
private PasswordEncoder encoder;
2528

2629

2730
@PostMapping(API_SIGN_IN)
2831
public ResponseEntity<JukeboxResponse> signInUser(@RequestBody LoginRequest request) {
29-
return authHelper.signInUser(request);
32+
return publicHelper.signInUser(request);
3033
}
3134

3235
@GetMapping(API_ENCRYPT)
3336
public ResponseEntity<JukeboxResponse> encrypt(@PathVariable String var){
3437
return ResponseEntity.ok(new SuccessResponse(encoder.encode(var)));
3538
}
39+
40+
@GetMapping(API_DOWNLOAD_FILE)
41+
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request){
42+
return publicHelper.downloadFile(fileName, request);
43+
}
3644
}

src/main/java/com/innoventes/jukebox/controller/helper/AuthHelper.java src/main/java/com/innoventes/jukebox/controller/helper/PublicHelper.java

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.innoventes.jukebox.controller.helper;
22

3+
import com.innoventes.jukebox.exceptions.JukeboxNotFoundException;
34
import com.innoventes.jukebox.models.request.LoginRequest;
45
import com.innoventes.jukebox.models.response.ErrorResponse;
56
import com.innoventes.jukebox.models.response.JukeboxResponse;
@@ -8,19 +9,26 @@
89
import com.innoventes.jukebox.security.UserDetailsImpl;
910
import com.innoventes.jukebox.security.UserDetailsServiceImpl;
1011
import com.innoventes.jukebox.security.jwt.JwtUtils;
12+
import com.innoventes.jukebox.service.StorageService;
1113
import org.slf4j.Logger;
1214
import org.slf4j.LoggerFactory;
1315
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.core.io.Resource;
17+
import org.springframework.http.HttpHeaders;
1418
import org.springframework.http.HttpStatus;
19+
import org.springframework.http.MediaType;
1520
import org.springframework.http.ResponseEntity;
1621
import org.springframework.security.authentication.AuthenticationManager;
1722
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
1823
import org.springframework.security.core.Authentication;
1924
import org.springframework.security.crypto.password.PasswordEncoder;
2025
import org.springframework.stereotype.Component;
2126

27+
import javax.servlet.http.HttpServletRequest;
28+
import java.io.IOException;
29+
2230
@Component
23-
public class AuthHelper {
31+
public class PublicHelper {
2432

2533
@Autowired
2634
private UserDetailsServiceImpl userService;
@@ -34,7 +42,10 @@ public class AuthHelper {
3442
@Autowired
3543
private AuthenticationManager authenticationManager;
3644

37-
private static final Logger LOGGER = LoggerFactory.getLogger(AuthHelper.class);
45+
@Autowired
46+
private StorageService storageService;
47+
48+
private static final Logger LOGGER = LoggerFactory.getLogger(PublicHelper.class);
3849

3950
public ResponseEntity<JukeboxResponse> signInUser(LoginRequest loginRequest){
4051
try{
@@ -53,4 +64,28 @@ public ResponseEntity<JukeboxResponse> signInUser(LoginRequest loginRequest){
5364
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ErrorResponse("Unable to Login, Please check credentials"));
5465
}
5566
}
67+
68+
public ResponseEntity<Resource> downloadFile(String fileName, HttpServletRequest request) {
69+
Resource resource = null;
70+
if (fileName != null && !fileName.isEmpty()){
71+
try{
72+
resource = storageService.loadFileAsResource(fileName);
73+
}catch (Exception ex){
74+
LOGGER.error(ex.getMessage());
75+
throw new JukeboxNotFoundException("File named " + fileName + " not found");
76+
}
77+
String contentType = null;
78+
try{
79+
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
80+
}catch (IOException ex){
81+
LOGGER.error("Could not determine the file type");
82+
contentType = "application/octet-stream";
83+
}
84+
return ResponseEntity.ok().contentType(MediaType.parseMediaType(contentType))
85+
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
86+
.body(resource);
87+
}else{
88+
return ResponseEntity.notFound().build();
89+
}
90+
}
5691
}

src/main/java/com/innoventes/jukebox/security/SecurityConfiguration.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
import org.springframework.security.authentication.AuthenticationManager;
99
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
1010
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11-
import org.springframework.security.config.annotation.web.builders.WebSecurity;
1211
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
1312
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
1413
import org.springframework.security.config.http.SessionCreationPolicy;
1514
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1615
import org.springframework.security.crypto.password.PasswordEncoder;
1716
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
1817

18+
import static com.innoventes.jukebox.constants.ApiConstants.*;
19+
1920
@Configuration
2021
@EnableWebSecurity
2122
@EnableGlobalMethodSecurity(prePostEnabled = true)
@@ -62,7 +63,8 @@ protected void configure(HttpSecurity http) throws Exception {
6263
.authorizeRequests()
6364
//This antMatcher filtering doesn't work.
6465
// The actual filtering is done in shouldNotFilter method in AuthTokenFilter class
65-
.antMatchers("/api/v1/auth/**").permitAll()
66+
.antMatchers(AUTHENTICATION_BASE_PATH + "/**").permitAll()
67+
.antMatchers(BASE_URL + DOWNLOAD_FILE_BASE_PATH + "**").permitAll()
6668
.antMatchers(
6769
"/v2/api-docs",
6870
"/swagger-resources/**",

src/main/java/com/innoventes/jukebox/security/jwt/AuthTokenFilter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public class AuthTokenFilter extends OncePerRequestFilter {
3434
@Override
3535
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
3636
String path = request.getRequestURI();
37-
return path.contains(ApiConstants.AUTHENTICATION_BASE_PATH)
37+
return path.contains(ApiConstants.AUTHENTICATION_BASE_PATH)
38+
|| path.contains(DOWNLOAD_FILE_BASE_PATH)
3839
|| path.contains(SWAGGER_UI_PATH)
3940
|| path.contains(SWAGGER_DOC_PATH)
4041
|| path.contains(SWAGGER_RESOURCES)

src/main/java/com/innoventes/jukebox/service/UserService.java

-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,4 @@ public interface UserService {
1919

2020
Boolean updateProfilePic(MultipartFile multipartFile, AbstractUser user);
2121

22-
Optional<FileStore> getProfilePic(AbstractUser user);
23-
2422
}

src/main/java/com/innoventes/jukebox/service/impl/StorageServiceImpl.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.nio.file.Path;
2323
import java.nio.file.Paths;
2424

25+
import static com.innoventes.jukebox.constants.ApiConstants.*;
26+
2527
@Service
2628
public class StorageServiceImpl implements StorageService {
2729

@@ -82,7 +84,7 @@ public Resource loadFileAsResource(String fileName) throws FileNotFoundException
8284
@Override
8385
public String getDownloadUrl(FileStore store) {
8486
return ServletUriComponentsBuilder.fromCurrentContextPath()
85-
.path("/downloadFile/")
87+
.path(BASE_URL + DOWNLOAD_FILE_BASE_PATH)
8688
.path(store.getName())
8789
.toUriString();
8890
}

src/main/java/com/innoventes/jukebox/service/impl/UserServiceImpl.java

-6
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,4 @@ public Boolean updateProfilePic(MultipartFile multipartFile, AbstractUser user)
8888
return true;
8989
}
9090

91-
@Override
92-
public Optional<FileStore> getProfilePic(AbstractUser user) {
93-
FileStore profilePic = user.getProfilePic();
94-
95-
return Optional.of(profilePic);
96-
}
9791
}

src/main/resources/application.properties

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ spring.jpa.hibernate.ddl-auto=update
1010
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
1111
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
1212

13+
#Multipart file configuration
14+
spring.servlet.multipart.max-file-size=600KB
15+
spring.servlet.multipart.max-request-size=600KB
16+
1317
#Flyway configuration
1418
flyway.url=jdbc:mysql://localhost:3306
1519
flyway.schemas=jukebox

src/test/java/com/innoventes/jukebox/controller/AuthControllerTest.java src/test/java/com/innoventes/jukebox/controller/PublicControllerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
1616

1717
@SpringBootTest
18-
public class AuthControllerTest extends AbstractControllerTest{
18+
public class PublicControllerTest extends AbstractControllerTest{
1919

2020

2121
@Test

0 commit comments

Comments
 (0)