From 9500668856a9e2b153a1e641f2ca492802d312aa Mon Sep 17 00:00:00 2001 From: Rohit Date: Tue, 2 Apr 2024 23:20:09 +0530 Subject: [PATCH 1/3] create blog response class with user and category details --- .../http/response/GetBlogFeedResponse.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main/java/com/example/BloggerApp/http/response/GetBlogFeedResponse.java diff --git a/src/main/java/com/example/BloggerApp/http/response/GetBlogFeedResponse.java b/src/main/java/com/example/BloggerApp/http/response/GetBlogFeedResponse.java new file mode 100644 index 0000000..3f3ded7 --- /dev/null +++ b/src/main/java/com/example/BloggerApp/http/response/GetBlogFeedResponse.java @@ -0,0 +1,51 @@ +package com.example.BloggerApp.http.response; + +import com.example.BloggerApp.models.Comment; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class GetBlogFeedResponse { + @JsonProperty("id") + private Long id; + + @JsonProperty("title") + private String title; + + @JsonProperty("subtitle") + private String subtitle; + + @JsonProperty("getTagResponses") + private List getTagResponses; + + @JsonProperty("content") + private String content; + + @JsonProperty("createdAt") + private String createdAt; + + @JsonProperty("cover") + private String imageCover; + + @JsonProperty("category") + private String category; + + @JsonProperty("authorName") + private String authorName; + + @JsonProperty("authorAvatar") + private String authorAvatar; + + @JsonProperty("comments") + public Set comments = new HashSet<>(); + +} From b87b1ed6df5c9825a575384c42727ab4bde0c50b Mon Sep 17 00:00:00 2001 From: Rohit Date: Tue, 2 Apr 2024 23:21:03 +0530 Subject: [PATCH 2/3] implement controller and service method for blog entity with user and category details --- .../BloggerApp/controller/BlogController.java | 14 +++++++++ .../BloggerApp/repository/BlogRepository.java | 7 +++++ .../service/impl/BlogServiceImpl.java | 31 +++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/main/java/com/example/BloggerApp/controller/BlogController.java b/src/main/java/com/example/BloggerApp/controller/BlogController.java index 6e8cf24..dbbb577 100644 --- a/src/main/java/com/example/BloggerApp/controller/BlogController.java +++ b/src/main/java/com/example/BloggerApp/controller/BlogController.java @@ -3,6 +3,7 @@ import com.example.BloggerApp.http.request.CreateBlogRequest; import com.example.BloggerApp.http.request.TagRequest; import com.example.BloggerApp.http.request.UpdateBlogRequest; +import com.example.BloggerApp.http.response.GetBlogFeedResponse; import com.example.BloggerApp.http.response.GetBlogResponse; import com.example.BloggerApp.http.response.GetTagResponse; import com.example.BloggerApp.models.BlogEntity; @@ -11,6 +12,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -36,12 +38,14 @@ public BlogController(BlogServiceImpl blogServiceImpl){ this.blogServiceImpl = blogServiceImpl; } + @CrossOrigin(origins = "http://localhost:3000",allowedHeaders = "*") @PostMapping("/create/user/{user_id}/category/{category_id}") public ResponseEntity createBlog(@RequestBody CreateBlogRequest createBlogRequest,@PathVariable("user_id") long userId,@PathVariable("category_id") long categoryId){ blogServiceImpl.addBlog(fromBlogRequestToBlogModel.apply(createBlogRequest),userId,categoryId); return new ResponseEntity<>("Blog Created",HttpStatus.CREATED); } + @CrossOrigin(origins = "http://localhost:3000") @GetMapping("/get-all") public ResponseEntity> getAllBlogs( @RequestParam(value = "pageNumber",defaultValue = "0",required = false) Integer pageNumber, @@ -52,6 +56,16 @@ public ResponseEntity> getAllBlogs( return new ResponseEntity<>(blogEntityList.stream().map(fromBlogModelToBlogResponse).collect(Collectors.toList()), HttpStatus.OK); } + @GetMapping("/get-all-info") + public ResponseEntity> getAllBlogsWithUserAndCategoryDetails( + @RequestParam(value = "pageNumber",defaultValue = "0",required = false) Integer pageNumber, + @RequestParam(value = "limit",defaultValue = "2",required = false) Integer limit + ){ + return new ResponseEntity<>(blogServiceImpl.getBlogWithUserAndCategoryDetails(pageNumber,limit), HttpStatus.OK); + } + + + @GetMapping("/get/{id}") public ResponseEntity getBlogById(@PathVariable("id") long id){ BlogEntity blogEntity = blogServiceImpl.getBlogById(id); diff --git a/src/main/java/com/example/BloggerApp/repository/BlogRepository.java b/src/main/java/com/example/BloggerApp/repository/BlogRepository.java index dde91cf..f073e54 100644 --- a/src/main/java/com/example/BloggerApp/repository/BlogRepository.java +++ b/src/main/java/com/example/BloggerApp/repository/BlogRepository.java @@ -3,6 +3,8 @@ import com.example.BloggerApp.models.BlogEntity; import com.example.BloggerApp.models.CategoryEntity; import com.example.BloggerApp.models.UserEntity; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -11,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Map; @Repository public interface BlogRepository extends JpaRepository { @@ -26,4 +29,8 @@ public interface BlogRepository extends JpaRepository { List getBlogByCategoryEntity(CategoryEntity categoryEntity); List getBlogByUserEntity(UserEntity userEntity); + + @Query(value = "SELECT mywork.blog_entity.id,mywork.blog_entity.title, mywork.category_entity.title as category,mywork.blog_entity.body,mywork.blog_entity.created_at,mywork.blog_entity.image_cover as cover,mywork.user_entity.image,mywork.user_entity.username from mywork.blog_entity inner join mywork.user_entity on mywork.blog_entity.user_entity_id=mywork.user_entity.id inner join mywork.category_entity on mywork.blog_entity.category_entity_id=mywork.category_entity.id ORDER BY mywork.blog_entity.id limit ?1 offset ?2 ;", + countQuery = "select count(*) from mywork.blog_entity;",nativeQuery = true) + List> findAllBlogEntitywithUserDetails(long limit,long offset); } diff --git a/src/main/java/com/example/BloggerApp/service/impl/BlogServiceImpl.java b/src/main/java/com/example/BloggerApp/service/impl/BlogServiceImpl.java index 0ad2355..d6fb05f 100644 --- a/src/main/java/com/example/BloggerApp/service/impl/BlogServiceImpl.java +++ b/src/main/java/com/example/BloggerApp/service/impl/BlogServiceImpl.java @@ -2,6 +2,8 @@ import com.example.BloggerApp.http.request.TagRequest; import com.example.BloggerApp.http.request.UpdateBlogRequest; +import com.example.BloggerApp.http.response.GetBlogFeedResponse; +import com.example.BloggerApp.http.response.GetBlogResponse; import com.example.BloggerApp.models.BlogEntity; import com.example.BloggerApp.models.CategoryEntity; import com.example.BloggerApp.models.TagEntity; @@ -15,7 +17,13 @@ import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; @@ -51,6 +59,12 @@ public BlogEntity getBlogById(long id){ return blogRepository.getById(id); } + public List getBlogWithUserAndCategoryDetails(int pageNumber,int limit){ + List> result=blogRepository.findAllBlogEntitywithUserDetails(limit,pageNumber); + List getBlogFeedResponseList = result.stream().map(fromMapToFeedResponse).collect(Collectors.toList()); + return getBlogFeedResponseList; + } + public BlogEntity deleteBlogById(long id){ return blogRepository.deleteById(id); } @@ -89,4 +103,21 @@ public List getBlogEntitiesByUserId(Long userId) { tagEntity.setTag(tagRequest.getTag()); return tagEntity; }; + + private final Function, GetBlogFeedResponse> fromMapToFeedResponse = + map ->{ + GetBlogFeedResponse getBlogFeedResponse = new GetBlogFeedResponse(); + BigInteger id = (BigInteger) map.get("id"); + getBlogFeedResponse.setId(id.longValue()); + getBlogFeedResponse.setTitle((String) map.get("title")); + getBlogFeedResponse.setContent((String) map.get("body")); + getBlogFeedResponse.setImageCover((String) map.get("cover")); + getBlogFeedResponse.setCategory((String) map.get("category")); + getBlogFeedResponse.setAuthorName((String) map.get("username")); + getBlogFeedResponse.setAuthorAvatar((String) map.get("image")); + Timestamp timestamp = (Timestamp) map.get("created_at"); + LocalDate localDate = timestamp.toLocalDateTime().toLocalDate(); + getBlogFeedResponse.setCreatedAt(""+localDate.getMonth()+" ,"+localDate.getDayOfMonth()+" "+localDate.getYear()); + return getBlogFeedResponse; + }; } From 582d4316e150a5edcd79006dd7bb18931ae29b30 Mon Sep 17 00:00:00 2001 From: Rohit Date: Tue, 2 Apr 2024 23:21:53 +0530 Subject: [PATCH 3/3] implement CORS logic to allow incoming request from UI --- .../configurations/SecurityConfig.java | 28 ++++++++++++++++++- .../controller/CategoryController.java | 2 ++ .../controller/LoginController.java | 23 ++++++++++++++- .../BloggerApp/controller/UserController.java | 5 ---- .../http/response/GetUserResponse.java | 2 ++ .../http/response/LoginResponse.java | 26 +++++++++++++++++ .../BloggerApp/service/UserService.java | 6 ++++ .../service/impl/UserServiceImpl.java | 5 ++++ 8 files changed, 90 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/BloggerApp/configurations/SecurityConfig.java b/src/main/java/com/example/BloggerApp/configurations/SecurityConfig.java index b3d8bb0..7049a5e 100644 --- a/src/main/java/com/example/BloggerApp/configurations/SecurityConfig.java +++ b/src/main/java/com/example/BloggerApp/configurations/SecurityConfig.java @@ -2,8 +2,10 @@ import com.example.BloggerApp.service.impl.CustomUserDetailService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -13,6 +15,12 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import java.util.Arrays; +import java.util.List; @Configuration @EnableWebSecurity @@ -33,7 +41,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { - http.csrf().disable().authorizeRequests().antMatchers(AppConstants.PUBLIC_URLS).permitAll().anyRequest().authenticated().and().exceptionHandling().authenticationEntryPoint(this.jwtAuthenticationEntryPoint).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + http.cors().and().csrf().disable().authorizeRequests().antMatchers(AppConstants.PUBLIC_URLS).permitAll(). + antMatchers(HttpMethod.GET).permitAll().anyRequest().authenticated().and().exceptionHandling().authenticationEntryPoint(this.jwtAuthenticationEntryPoint).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } @@ -48,4 +57,21 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } + @Bean + public FilterRegistrationBean coresFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowCredentials(true); + configuration.addAllowedOriginPattern("*"); + configuration.addAllowedMethod("POST"); + configuration.addAllowedMethod("GET"); + configuration.addAllowedHeader("Authorization"); + configuration.addAllowedHeader("Accept"); + configuration.addAllowedHeader("Content-Type"); + + source.registerCorsConfiguration("/**", configuration); + FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); + bean.setOrder(-110); + return bean; + } } diff --git a/src/main/java/com/example/BloggerApp/controller/CategoryController.java b/src/main/java/com/example/BloggerApp/controller/CategoryController.java index b3edb2a..552fe66 100644 --- a/src/main/java/com/example/BloggerApp/controller/CategoryController.java +++ b/src/main/java/com/example/BloggerApp/controller/CategoryController.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +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.PathVariable; @@ -38,6 +39,7 @@ public ResponseEntity getCategoryById(@PathVariable("id") l return new ResponseEntity<>(categoryServiceImpl.getCategoryById(id), HttpStatus.OK); } + @CrossOrigin(origins = "http://localhost:3000") @GetMapping("/get-all") public ResponseEntity> getCategoryList( @RequestParam(value = "pageNumber",defaultValue = "0",required = false) Integer pageNumber, diff --git a/src/main/java/com/example/BloggerApp/controller/LoginController.java b/src/main/java/com/example/BloggerApp/controller/LoginController.java index 07bf5dd..254c3bc 100644 --- a/src/main/java/com/example/BloggerApp/controller/LoginController.java +++ b/src/main/java/com/example/BloggerApp/controller/LoginController.java @@ -1,8 +1,12 @@ package com.example.BloggerApp.controller; import com.example.BloggerApp.configurations.JWTTokenHelper; +import com.example.BloggerApp.http.request.CreateUser; import com.example.BloggerApp.http.request.LoginRequest; +import com.example.BloggerApp.http.response.GetUserResponse; import com.example.BloggerApp.http.response.LoginResponse; +import com.example.BloggerApp.models.UserEntity; +import com.example.BloggerApp.service.UserService; import com.example.BloggerApp.service.impl.CustomUserDetailService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -29,6 +33,9 @@ public class LoginController { @Autowired private CustomUserDetailService customUserDetailService; + @Autowired + private UserService userService; + @CrossOrigin(origins = "http://localhost:3000") @PostMapping("/login") public ResponseEntity createToken(@RequestBody LoginRequest loginRequest){ @@ -36,12 +43,26 @@ public ResponseEntity createToken(@RequestBody LoginRequest login UserDetails userDetails = customUserDetailService.loadUserByUsername(loginRequest.getUsername()); String token = jwtTokenHelper.generateToken(userDetails); - + UserEntity userEntity = userService.getUserEntityByUsername(loginRequest.getUsername()); LoginResponse loginResponse = new LoginResponse(); loginResponse.setToken(token); + loginResponse.setUserId(userEntity.getId()); + loginResponse.setUsername(userEntity.getUsername()); + loginResponse.setEmail(userEntity.getEmail()); + loginResponse.setImage(userEntity.getImage()); + loginResponse.setCreatedDate(userEntity.getCreatedDate()); + loginResponse.setAbout(userEntity.getBio()); + loginResponse.setRoles(userEntity.getRoles()); return new ResponseEntity<>(loginResponse, HttpStatus.CREATED); } + @CrossOrigin(origins = "http://localhost:3000") + @PostMapping("/register") + public ResponseEntity registerUser(@RequestBody CreateUser createUser){ + GetUserResponse getUserResponse = userService.registerUser(createUser); + return new ResponseEntity<>(getUserResponse,HttpStatus.CREATED); + } + private void authenticate(String email, String password) { UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(email,password); diff --git a/src/main/java/com/example/BloggerApp/controller/UserController.java b/src/main/java/com/example/BloggerApp/controller/UserController.java index 025555b..58a6eeb 100644 --- a/src/main/java/com/example/BloggerApp/controller/UserController.java +++ b/src/main/java/com/example/BloggerApp/controller/UserController.java @@ -74,11 +74,6 @@ public ResponseEntity deleteUserById(@PathVariable("id") Long id){ return new ResponseEntity<>("User Deleted",HttpStatus.ACCEPTED); } - @PostMapping("/register") - public ResponseEntity registerUser(@RequestBody CreateUser createUser){ - GetUserResponse getUserResponse = userServiceImpl.registerUser(createUser); - return new ResponseEntity<>(getUserResponse,HttpStatus.CREATED); - } private final Function fromUpdateUserRequestToUserEntity = updateUser -> { diff --git a/src/main/java/com/example/BloggerApp/http/response/GetUserResponse.java b/src/main/java/com/example/BloggerApp/http/response/GetUserResponse.java index 539900e..65b1b78 100644 --- a/src/main/java/com/example/BloggerApp/http/response/GetUserResponse.java +++ b/src/main/java/com/example/BloggerApp/http/response/GetUserResponse.java @@ -1,6 +1,7 @@ package com.example.BloggerApp.http.response; import com.example.BloggerApp.models.Roles; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.NoArgsConstructor; @@ -22,6 +23,7 @@ public class GetUserResponse { public String email; + @JsonIgnore public String password; public String image; diff --git a/src/main/java/com/example/BloggerApp/http/response/LoginResponse.java b/src/main/java/com/example/BloggerApp/http/response/LoginResponse.java index 6713545..531276f 100644 --- a/src/main/java/com/example/BloggerApp/http/response/LoginResponse.java +++ b/src/main/java/com/example/BloggerApp/http/response/LoginResponse.java @@ -1,11 +1,37 @@ package com.example.BloggerApp.http.response; +import com.example.BloggerApp.models.Roles; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + @Data public class LoginResponse { @JsonProperty("token") private String token; + + @JsonProperty("userId") + public Long userId; + + @JsonProperty("username") + public String username; + + @JsonProperty("email") + public String email; + + @JsonProperty("image") + public String image; + + @JsonProperty("about") + public String about; + + @JsonProperty("createdDate") + public Date createdDate; + + @JsonProperty("roles") + public Set roles = new HashSet<>(); } diff --git a/src/main/java/com/example/BloggerApp/service/UserService.java b/src/main/java/com/example/BloggerApp/service/UserService.java index cda4393..d4bc3f2 100644 --- a/src/main/java/com/example/BloggerApp/service/UserService.java +++ b/src/main/java/com/example/BloggerApp/service/UserService.java @@ -1,5 +1,7 @@ package com.example.BloggerApp.service; +import com.example.BloggerApp.http.request.CreateUser; +import com.example.BloggerApp.http.response.GetUserResponse; import com.example.BloggerApp.models.UserEntity; import java.util.List; @@ -16,5 +18,9 @@ public interface UserService { void deleteUseryId(Long id); + GetUserResponse registerUser(CreateUser createUser); + + UserEntity getUserEntityByUsername(String username); + } diff --git a/src/main/java/com/example/BloggerApp/service/impl/UserServiceImpl.java b/src/main/java/com/example/BloggerApp/service/impl/UserServiceImpl.java index 9bcdf70..9602e7e 100644 --- a/src/main/java/com/example/BloggerApp/service/impl/UserServiceImpl.java +++ b/src/main/java/com/example/BloggerApp/service/impl/UserServiceImpl.java @@ -84,4 +84,9 @@ public GetUserResponse registerUser(CreateUser createUser){ return getUserResponse; } + + @Override + public UserEntity getUserEntityByUsername(String username) { + return userRepository.findUserEntityByUsername(username); + } }