From ece7c29e2cb3c1904aab39f14799fe52ed133309 Mon Sep 17 00:00:00 2001 From: ABDERRAOUF MAKHLOUF Date: Sun, 6 Sep 2020 11:56:23 +0200 Subject: [PATCH 01/20] chore() use-lombok-library --- .github/workflows/greetings.yml | 12 +- docker-compose.yml | 54 +-- pom.xml | 337 +++++++++--------- .../blogapi/BlogApiApplication.java | 12 +- .../blogapi/config/AuditingConfig.java | 28 +- .../blogapi/config/SecutiryConfig.java | 91 +++-- .../blogapi/config/WebMvcConfig.java | 20 +- .../blogapi/controller/AlbumController.java | 39 +- .../blogapi/controller/AuthController.java | 40 +-- .../controller/CategoryController.java | 21 +- .../blogapi/controller/CommentController.java | 47 ++- .../blogapi/controller/PhotoController.java | 37 +- .../blogapi/controller/PostController.java | 49 ++- .../blogapi/controller/TagController.java | 103 +++--- .../blogapi/controller/TodoController.java | 144 ++++---- .../blogapi/controller/UserController.java | 81 +++-- .../exception/AccessDeniedException.java | 13 +- .../exception/BadRequestException.java | 9 +- .../blogapi/exception/BlogapiException.java | 8 +- .../exception/ResourceNotFoundException.java | 9 +- .../ResponseEntityErrorException.java | 7 +- .../RestControllerExceptionHandler.java | 56 ++- .../exception/UnauthorizedException.java | 13 +- .../blogapi/model/{album => }/Album.java | 38 +- .../model/{category => }/Category.java | 46 +-- .../com/sopromadze/blogapi/model/Comment.java | 70 ++++ .../blogapi/model/{photo => }/Photo.java | 54 +-- .../blogapi/model/{post => }/Post.java | 56 +-- .../blogapi/model/{tag => }/Tag.java | 39 +- .../blogapi/model/{todo => }/Todo.java | 40 +-- .../blogapi/model/audit/DateAudit.java | 31 +- .../blogapi/model/audit/UserDateAudit.java | 32 +- .../blogapi/model/comment/Comment.java | 111 ------ .../sopromadze/blogapi/model/role/Role.java | 57 ++- .../blogapi/model/role/RoleName.java | 4 +- .../blogapi/model/user/Address.java | 60 +--- .../blogapi/model/user/Company.java | 38 +- .../sopromadze/blogapi/model/user/Geo.java | 39 +- .../sopromadze/blogapi/model/user/User.java | 123 ++----- .../blogapi/payload/AlbumResponse.java | 40 +-- .../blogapi/payload/ApiResponse.java | 65 ++-- .../blogapi/payload/CommentRequest.java | 17 +- .../blogapi/payload/DateAuditPayload.java | 28 +- .../blogapi/payload/ExceptionResponse.java | 56 +-- .../blogapi/payload/InfoRequest.java | 91 +---- .../payload/JwtAuthenticationResponse.java | 28 +- .../blogapi/payload/LoginRequest.java | 27 +- .../blogapi/payload/PagedResponse.java | 91 ++--- .../blogapi/payload/PhotoRequest.java | 57 +-- .../blogapi/payload/PhotoResponse.java | 68 +--- .../blogapi/payload/PostRequest.java | 36 +- .../blogapi/payload/PostResponse.java | 38 +- .../blogapi/payload/SignUpRequest.java | 83 ++--- .../blogapi/payload/UserDateAuditPayload.java | 23 +- .../payload/UserIdentityAvailability.java | 18 +- .../blogapi/payload/UserProfile.java | 134 +------ .../blogapi/payload/UserSummary.java | 52 +-- .../blogapi/payload/request/AlbumRequest.java | 38 +- .../blogapi/repository/AlbumRepository.java | 5 +- .../repository/CategoryRepository.java | 3 +- .../blogapi/repository/CommentRepository.java | 3 +- .../blogapi/repository/PhotoRepository.java | 3 +- .../blogapi/repository/PostRepository.java | 18 +- .../blogapi/repository/RoleRepository.java | 7 +- .../blogapi/repository/TagRepository.java | 3 +- .../blogapi/repository/TodoRepository.java | 3 +- .../blogapi/repository/UserRepository.java | 8 +- .../blogapi/security/CurrentUser.java | 8 +- .../security/JwtAuthenticationEntryPoint.java | 14 +- .../security/JwtAuthenticationFilter.java | 75 ++-- .../blogapi/security/JwtTokenProvider.java | 95 +++-- .../blogapi/security/UserPrincipal.java | 15 +- .../blogapi/service/AlbumService.java | 7 +- .../blogapi/service/CategoryService.java | 7 +- .../blogapi/service/CommentService.java | 4 +- .../blogapi/service/PostService.java | 4 +- .../blogapi/service/TagService.java | 4 +- .../blogapi/service/TodoService.java | 4 +- .../service/impl/AlbumServiceImpl.java | 209 +++++------ .../service/impl/CategoryServiceImpl.java | 102 +++--- .../service/impl/CommentServiceImpl.java | 34 +- .../impl/CustomUserDetailsServiceImpl.java | 26 +- .../service/impl/PhotoServiceImpl.java | 55 ++- .../blogapi/service/impl/PostServiceImpl.java | 59 ++- .../blogapi/service/impl/TagServiceImpl.java | 106 +++--- .../blogapi/service/impl/TodoServiceImpl.java | 78 ++-- .../blogapi/service/impl/UserServiceImpl.java | 33 +- .../blogapi/utils/AppConstants.java | 54 +-- .../sopromadze/blogapi/utils/AppUtils.java | 23 +- src/main/resources/application.properties | 29 +- .../com/sopromadze/blogapi/AbstractTest.java | 10 +- .../blogapi/BlogApiApplicationTests.java | 6 +- .../blogapi/model/album/AlbumTest.java | 16 +- .../sopromadze/blogapi/utils/TestUtils.java | 26 +- 94 files changed, 1626 insertions(+), 2588 deletions(-) rename src/main/java/com/sopromadze/blogapi/model/{album => }/Album.java (81%) rename src/main/java/com/sopromadze/blogapi/model/{category => }/Category.java (77%) create mode 100644 src/main/java/com/sopromadze/blogapi/model/Comment.java rename src/main/java/com/sopromadze/blogapi/model/{photo => }/Photo.java (67%) rename src/main/java/com/sopromadze/blogapi/model/{post => }/Post.java (79%) rename src/main/java/com/sopromadze/blogapi/model/{tag => }/Tag.java (82%) rename src/main/java/com/sopromadze/blogapi/model/{todo => }/Todo.java (71%) delete mode 100644 src/main/java/com/sopromadze/blogapi/model/comment/Comment.java diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index c691b593..bc948db8 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -1,13 +1,13 @@ name: Greetings -on: [pull_request, issues] +on: [ pull_request, issues ] jobs: greeting: runs-on: ubuntu-latest steps: - - uses: actions/first-interaction@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: 'Welcome to Spring-Boot-Blog-REST-API community! Thanks so much for creating your first issue :)' - pr-message: 'Thanks so much for creating your first PR, the Spring-Boot-Blog-REST-API community thanks you :)' + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: 'Welcome to Spring-Boot-Blog-REST-API community! Thanks so much for creating your first issue :)' + pr-message: 'Thanks so much for creating your first PR, the Spring-Boot-Blog-REST-API community thanks you :)' diff --git a/docker-compose.yml b/docker-compose.yml index 8835e6fa..c098f3df 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,29 @@ version: '3' services: - mysql: - image: mysql - restart: always - environment: - MYSQL_DATABASE: 'blogapi' - MYSQL_USER: 'root' - MYSQL_PASSWORD: 'root' - MYSQL_ROOT_PASSWORD: 'root' - ports: - - '3306' - networks: - - production-network - application: - build: - dockerfile: ./Dockerfile - context: . - image: michel-eckhardt/spring-boot-blog - container_name: spring-boot-blog - ports: - - "8080:8080" - networks: - - production-network - depends_on: - - "mysql" -networks: - production-network: - driver: bridge \ No newline at end of file + mysql: + image: mysql + restart: always + environment: + MYSQL_DATABASE: 'blogapi' + MYSQL_USER: 'root' + MYSQL_PASSWORD: 'root' + MYSQL_ROOT_PASSWORD: 'root' + ports: + - '3306' + networks: + - production-network + application: + build: + dockerfile: ./Dockerfile + context: . + image: michel-eckhardt/spring-boot-blog + container_name: spring-boot-blog + ports: + - "8080:8080" + networks: + - production-network + depends_on: + - "mysql" +networks: + production-network: + driver: bridge diff --git a/pom.xml b/pom.xml index 79747541..8d69a6f4 100644 --- a/pom.xml +++ b/pom.xml @@ -1,172 +1,181 @@ - - 4.0.0 - - com.sopromadze - blogapi - 0.0.1-SNAPSHOT - jar - - BlogAPI - Blog API project with Spring Boot - - - org.springframework.boot - spring-boot-starter-parent - 2.1.8.RELEASE - - - - - UTF-8 - UTF-8 - 1.8 - - - - - org.springframework.boot - spring-boot-starter - - - - mysql - mysql-connector-java - runtime - - - - org.springframework.boot - spring-boot-starter-web - - - + + 4.0.0 + + com.sopromadze + blogapi + 0.0.1-SNAPSHOT + jar + + BlogAPI + Blog API project with Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.1.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter + + + + mysql + mysql-connector-java + runtime + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot spring-boot-starter-aop - - - org.springframework.boot - spring-boot-starter-test - test - - - - - org.mockito - mockito-all - 2.0.2-beta - test - - - - - org.springframework.security - spring-security-test - test - - - - - - org.hamcrest - hamcrest-library - test - - - - - org.modelmapper - modelmapper - 2.3.5 - - - - - org.springframework.boot - spring-boot-devtools - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.boot - spring-boot-starter-security - - - - org.springframework.security - spring-security-jwt - 1.0.9.RELEASE - - - - org.springframework.security.oauth - spring-security-oauth2 - 2.3.4.RELEASE - - - - io.jsonwebtoken - jjwt - 0.9.1 - - - - javax.xml.bind - jaxb-api - - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - - org.apache.commons - commons-lang3 - - - - org.modelmapper - modelmapper - 2.3.1 - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - com.sopromadze.blogapi.BlogApiApplication - - - - - repackage - - - - - - + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.mockito + mockito-all + 2.0.2-beta + test + + + + + org.springframework.security + spring-security-test + test + + + + + + org.hamcrest + hamcrest-library + test + + + + + org.modelmapper + modelmapper + 2.3.5 + + + + + + org.projectlombok + lombok + 1.18.12 + provided + + + + + org.springframework.boot + spring-boot-devtools + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security + spring-security-jwt + 1.0.9.RELEASE + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.3.4.RELEASE + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + javax.xml.bind + jaxb-api + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + org.apache.commons + commons-lang3 + + + + org.modelmapper + modelmapper + 2.3.1 + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.sopromadze.blogapi.BlogApiApplication + + + + + repackage + + + + + + diff --git a/src/main/java/com/sopromadze/blogapi/BlogApiApplication.java b/src/main/java/com/sopromadze/blogapi/BlogApiApplication.java index 925c82bc..6e45ce6b 100644 --- a/src/main/java/com/sopromadze/blogapi/BlogApiApplication.java +++ b/src/main/java/com/sopromadze/blogapi/BlogApiApplication.java @@ -1,9 +1,6 @@ package com.sopromadze.blogapi; -import java.util.TimeZone; - -import javax.annotation.PostConstruct; - +import com.sopromadze.blogapi.security.JwtAuthenticationFilter; import org.modelmapper.ModelMapper; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -11,7 +8,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.data.convert.Jsr310Converters; -import com.sopromadze.blogapi.security.JwtAuthenticationFilter; +import javax.annotation.PostConstruct; +import java.util.TimeZone; @SpringBootApplication @EntityScan(basePackageClasses = { BlogApiApplication.class, Jsr310Converters.class }) @@ -31,10 +29,10 @@ void init() { public JwtAuthenticationFilter jwtAuthenticationFilter() { return new JwtAuthenticationFilter(); } - + @Bean public ModelMapper modelMapper() { - return new ModelMapper(); + return new ModelMapper(); } } diff --git a/src/main/java/com/sopromadze/blogapi/config/AuditingConfig.java b/src/main/java/com/sopromadze/blogapi/config/AuditingConfig.java index 2d820eae..144a9444 100644 --- a/src/main/java/com/sopromadze/blogapi/config/AuditingConfig.java +++ b/src/main/java/com/sopromadze/blogapi/config/AuditingConfig.java @@ -15,24 +15,24 @@ @EnableJpaAuditing public class AuditingConfig { - @Bean - public AuditorAware auditorProvider(){ - return new SpringSecurityAuditAwareImpl(); - } + @Bean + public AuditorAware auditorProvider() { + return new SpringSecurityAuditAwareImpl(); + } } -class SpringSecurityAuditAwareImpl implements AuditorAware{ +class SpringSecurityAuditAwareImpl implements AuditorAware { - @Override - public Optional getCurrentAuditor() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + @Override + public Optional getCurrentAuditor() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if(authentication == null || !authentication.isAuthenticated() || authentication instanceof AnonymousAuthenticationToken) { - return Optional.empty(); - } + if (authentication == null || !authentication.isAuthenticated() || authentication instanceof AnonymousAuthenticationToken) { + return Optional.empty(); + } - UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(); + UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(); - return Optional.ofNullable(userPrincipal.getId()); - } + return Optional.ofNullable(userPrincipal.getId()); + } } diff --git a/src/main/java/com/sopromadze/blogapi/config/SecutiryConfig.java b/src/main/java/com/sopromadze/blogapi/config/SecutiryConfig.java index bfa387f8..1a0c1175 100644 --- a/src/main/java/com/sopromadze/blogapi/config/SecutiryConfig.java +++ b/src/main/java/com/sopromadze/blogapi/config/SecutiryConfig.java @@ -1,5 +1,9 @@ package com.sopromadze.blogapi.config; +import com.sopromadze.blogapi.repository.UserRepository; +import com.sopromadze.blogapi.security.JwtAuthenticationEntryPoint; +import com.sopromadze.blogapi.security.JwtAuthenticationFilter; +import com.sopromadze.blogapi.service.impl.CustomUserDetailsServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,62 +20,57 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import com.sopromadze.blogapi.repository.UserRepository; -import com.sopromadze.blogapi.security.JwtAuthenticationEntryPoint; -import com.sopromadze.blogapi.security.JwtAuthenticationFilter; -import com.sopromadze.blogapi.service.impl.CustomUserDetailsServiceImpl; - @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity( - securedEnabled = true, - jsr250Enabled = true, - prePostEnabled = true) + securedEnabled = true, + jsr250Enabled = true, + prePostEnabled = true) public class SecutiryConfig extends WebSecurityConfigurerAdapter { - private final CustomUserDetailsServiceImpl customUserDetailsService; - private final JwtAuthenticationEntryPoint unauthorizedHandler; - private final JwtAuthenticationFilter jwtAuthenticationFilter; + private final CustomUserDetailsServiceImpl customUserDetailsService; + private final JwtAuthenticationEntryPoint unauthorizedHandler; + private final JwtAuthenticationFilter jwtAuthenticationFilter; - @Autowired - public SecutiryConfig(UserRepository userRepository, CustomUserDetailsServiceImpl customUserDetailsService, JwtAuthenticationEntryPoint unauthorizedHandler, JwtAuthenticationFilter jwtAuthenticationFilter) { - this.customUserDetailsService = customUserDetailsService; - this.unauthorizedHandler = unauthorizedHandler; - this.jwtAuthenticationFilter = jwtAuthenticationFilter; - } + @Autowired + public SecutiryConfig(UserRepository userRepository, CustomUserDetailsServiceImpl customUserDetailsService, + JwtAuthenticationEntryPoint unauthorizedHandler, JwtAuthenticationFilter jwtAuthenticationFilter) { + this.customUserDetailsService = customUserDetailsService; + this.unauthorizedHandler = unauthorizedHandler; + this.jwtAuthenticationFilter = jwtAuthenticationFilter; + } - @Override - protected void configure(HttpSecurity http) throws Exception { - - http.cors().and().csrf().disable() - .exceptionHandling() - .authenticationEntryPoint(unauthorizedHandler) - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() - .antMatchers(HttpMethod.GET, "/api/**").permitAll() - .antMatchers(HttpMethod.POST, "/api/auth/**").permitAll() - .antMatchers(HttpMethod.GET, "/api/users/checkUsernameAvailability", "/api/users/checkEmailAvailability").permitAll() - .anyRequest().authenticated(); + @Override + protected void configure(HttpSecurity http) throws Exception { - http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + http.cors().and().csrf().disable() + .exceptionHandling() + .authenticationEntryPoint(unauthorizedHandler) + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + .antMatchers(HttpMethod.GET, "/api/**").permitAll() + .antMatchers(HttpMethod.POST, "/api/auth/**").permitAll() + .antMatchers(HttpMethod.GET, "/api/users/checkUsernameAvailability", "/api/users/checkEmailAvailability").permitAll() + .anyRequest().authenticated(); + http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); - } + } - public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { - authenticationManagerBuilder.userDetailsService(customUserDetailsService) - .passwordEncoder(passwordEncoder()); - } + public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { + authenticationManagerBuilder.userDetailsService(customUserDetailsService) + .passwordEncoder(passwordEncoder()); + } - @Bean(BeanIds.AUTHENTICATION_MANAGER) - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } + @Bean(BeanIds.AUTHENTICATION_MANAGER) + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/src/main/java/com/sopromadze/blogapi/config/WebMvcConfig.java b/src/main/java/com/sopromadze/blogapi/config/WebMvcConfig.java index dbde38f6..301ecb17 100644 --- a/src/main/java/com/sopromadze/blogapi/config/WebMvcConfig.java +++ b/src/main/java/com/sopromadze/blogapi/config/WebMvcConfig.java @@ -7,17 +7,17 @@ @Configuration public class WebMvcConfig implements WebMvcConfigurer { - + @Value("cors.allowedOrings") private String allowedOrigins; - public void addCorsMappings(CorsRegistry registry){ - final long MAX_AGE_SECS = 3600; - - registry.addMapping("/**") - .allowedOrigins(allowedOrigins) - .allowedMethods("GET", "POST", "PUT", "DELETE") - .allowedHeaders("*") - .maxAge(MAX_AGE_SECS); - } + public void addCorsMappings(CorsRegistry registry) { + final long MAX_AGE_SECS = 3600; + + registry.addMapping("/**") + .allowedOrigins(allowedOrigins) + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .maxAge(MAX_AGE_SECS); + } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/AlbumController.java b/src/main/java/com/sopromadze/blogapi/controller/AlbumController.java index 3966ea45..b5dc9ff4 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/AlbumController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/AlbumController.java @@ -1,7 +1,18 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.exception.ResponseEntityErrorException; +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.payload.AlbumResponse; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.payload.PhotoResponse; +import com.sopromadze.blogapi.payload.request.AlbumRequest; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.AlbumService; +import com.sopromadze.blogapi.service.PhotoService; +import com.sopromadze.blogapi.utils.AppConstants; +import com.sopromadze.blogapi.utils.AppUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,19 +28,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.exception.ResponseEntityErrorException; -import com.sopromadze.blogapi.model.album.Album; -import com.sopromadze.blogapi.payload.AlbumResponse; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.payload.PhotoResponse; -import com.sopromadze.blogapi.payload.request.AlbumRequest; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.AlbumService; -import com.sopromadze.blogapi.service.PhotoService; -import com.sopromadze.blogapi.utils.AppConstants; -import com.sopromadze.blogapi.utils.AppUtils; +import javax.validation.Valid; @RestController @RequestMapping("/api/albums") @@ -39,7 +38,7 @@ public class AlbumController { @Autowired private PhotoService photoService; - + @ExceptionHandler(ResponseEntityErrorException.class) public ResponseEntity handleExceptions(ResponseEntityErrorException exception) { return exception.getApiResponse(); @@ -50,7 +49,7 @@ public PagedResponse getAllAlbums( @RequestParam(name = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { AppUtils.validatePageNumberAndSize(page, size); - + return albumService.getAllAlbums(page, size); } @@ -82,10 +81,10 @@ public ResponseEntity deleteAlbum(@PathVariable(name = "id") Long i public ResponseEntity> getAllPhotosByAlbum(@PathVariable(name = "id") Long id, @RequestParam(name = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { - + PagedResponse response = photoService.getAllPhotosByAlbum(id, page, size); - - return new ResponseEntity>(response, HttpStatus.OK); + + return new ResponseEntity<>(response, HttpStatus.OK); } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/AuthController.java b/src/main/java/com/sopromadze/blogapi/controller/AuthController.java index ff8dc5d9..fce9d3b0 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/AuthController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/AuthController.java @@ -1,11 +1,17 @@ package com.sopromadze.blogapi.controller; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import javax.validation.Valid; - +import com.sopromadze.blogapi.exception.AppException; +import com.sopromadze.blogapi.exception.BlogapiException; +import com.sopromadze.blogapi.model.role.Role; +import com.sopromadze.blogapi.model.role.RoleName; +import com.sopromadze.blogapi.model.user.User; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.JwtAuthenticationResponse; +import com.sopromadze.blogapi.payload.LoginRequest; +import com.sopromadze.blogapi.payload.SignUpRequest; +import com.sopromadze.blogapi.repository.RoleRepository; +import com.sopromadze.blogapi.repository.UserRepository; +import com.sopromadze.blogapi.security.JwtTokenProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,18 +26,10 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import com.sopromadze.blogapi.exception.AppException; -import com.sopromadze.blogapi.exception.BlogapiException; -import com.sopromadze.blogapi.model.role.Role; -import com.sopromadze.blogapi.model.role.RoleName; -import com.sopromadze.blogapi.model.user.User; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.JwtAuthenticationResponse; -import com.sopromadze.blogapi.payload.LoginRequest; -import com.sopromadze.blogapi.payload.SignUpRequest; -import com.sopromadze.blogapi.repository.RoleRepository; -import com.sopromadze.blogapi.repository.UserRepository; -import com.sopromadze.blogapi.security.JwtTokenProvider; +import javax.validation.Valid; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; @RestController @RequestMapping("/api/auth") @@ -73,7 +71,7 @@ public ResponseEntity registerUser(@Valid @RequestBody SignUpReques if (userRepository.existsByEmail(signUpRequest.getEmail())) { throw new BlogapiException(HttpStatus.BAD_REQUEST, "Email is already taken"); } - + String firstName = signUpRequest.getFirstName().toLowerCase(); String lastName = signUpRequest.getLastName().toLowerCase(); @@ -81,13 +79,13 @@ public ResponseEntity registerUser(@Valid @RequestBody SignUpReques String username = signUpRequest.getUsername().toLowerCase(); String email = signUpRequest.getEmail().toLowerCase(); - + String password = passwordEncoder.encode(signUpRequest.getPassword()); User user = new User(firstName, lastName, username, email, password); List roles = new ArrayList<>(); - + if (userRepository.count() == 0) { roles.add(roleRepository.findByName(RoleName.ROLE_USER) .orElseThrow(() -> new AppException(USER_ROLE_NOT_SET))); diff --git a/src/main/java/com/sopromadze/blogapi/controller/CategoryController.java b/src/main/java/com/sopromadze/blogapi/controller/CategoryController.java index 260228cf..39b63842 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/CategoryController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/CategoryController.java @@ -1,7 +1,13 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.exception.UnauthorizedException; +import com.sopromadze.blogapi.model.Category; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.CategoryService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -15,14 +21,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.category.Category; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.CategoryService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/categories") @@ -41,7 +40,7 @@ public PagedResponse getAllCategories( @PreAuthorize("hasRole('USER')") public ResponseEntity addCategory(@Valid @RequestBody Category category, @CurrentUser UserPrincipal currentUser) { - + return categoryService.addCategory(category, currentUser); } diff --git a/src/main/java/com/sopromadze/blogapi/controller/CommentController.java b/src/main/java/com/sopromadze/blogapi/controller/CommentController.java index fac1dbde..2a402910 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/CommentController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/CommentController.java @@ -1,7 +1,13 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.model.Comment; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.CommentRequest; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.CommentService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,14 +22,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.model.comment.Comment; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.CommentRequest; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.CommentService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/posts/{postId}/comments") @@ -35,10 +34,10 @@ public class CommentController { public ResponseEntity> getAllComments(@PathVariable(name = "postId") Long postId, @RequestParam(name = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { - + PagedResponse allComments = commentService.getAllComments(postId, page, size); - - return new ResponseEntity>(allComments, HttpStatus.OK); + + return new ResponseEntity< >(allComments, HttpStatus.OK); } @PostMapping @@ -46,16 +45,16 @@ public ResponseEntity> getAllComments(@PathVariable(name public ResponseEntity addComment(@Valid @RequestBody CommentRequest commentRequest, @PathVariable(name = "postId") Long postId, @CurrentUser UserPrincipal currentUser) { Comment newComment = commentService.addComment(commentRequest, postId, currentUser); - - return new ResponseEntity(newComment, HttpStatus.CREATED); + + return new ResponseEntity<>(newComment, HttpStatus.CREATED); } @GetMapping("/{id}") public ResponseEntity getComment(@PathVariable(name = "postId") Long postId, @PathVariable(name = "id") Long id) { Comment comment = commentService.getComment(postId, id); - - return new ResponseEntity(comment, HttpStatus.OK); + + return new ResponseEntity<>(comment, HttpStatus.OK); } @PutMapping("/{id}") @@ -63,22 +62,22 @@ public ResponseEntity getComment(@PathVariable(name = "postId") Long po public ResponseEntity updateComment(@PathVariable(name = "postId") Long postId, @PathVariable(name = "id") Long id, @Valid @RequestBody CommentRequest commentRequest, @CurrentUser UserPrincipal currentUser) { - + Comment updatedComment = commentService.updateComment(postId, id, commentRequest, currentUser); - - return new ResponseEntity(updatedComment, HttpStatus.OK); + + return new ResponseEntity<>(updatedComment, HttpStatus.OK); } @DeleteMapping("/{id}") @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") public ResponseEntity deleteComment(@PathVariable(name = "postId") Long postId, @PathVariable(name = "id") Long id, @CurrentUser UserPrincipal currentUser) { - + ApiResponse response = commentService.deleteComment(postId, id, currentUser); - + HttpStatus status = response.getSuccess() ? HttpStatus.OK : HttpStatus.BAD_REQUEST; - - return new ResponseEntity(response, status); + + return new ResponseEntity<>(response, status); } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/PhotoController.java b/src/main/java/com/sopromadze/blogapi/controller/PhotoController.java index d5570e16..2f0846d0 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/PhotoController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/PhotoController.java @@ -1,7 +1,13 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.payload.PhotoRequest; +import com.sopromadze.blogapi.payload.PhotoResponse; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.PhotoService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,14 +22,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.payload.PhotoRequest; -import com.sopromadze.blogapi.payload.PhotoResponse; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.PhotoService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/photos") @@ -43,32 +42,32 @@ public PagedResponse getAllPhotos( public ResponseEntity addPhoto(@Valid @RequestBody PhotoRequest photoRequest, @CurrentUser UserPrincipal currentUser) { PhotoResponse photoResponse = photoService.addPhoto(photoRequest, currentUser); - - return new ResponseEntity(photoResponse, HttpStatus.OK); + + return new ResponseEntity< >(photoResponse, HttpStatus.OK); } @GetMapping("/{id}") public ResponseEntity getPhoto(@PathVariable(name = "id") Long id) { PhotoResponse photoResponse = photoService.getPhoto(id); - - return new ResponseEntity(photoResponse, HttpStatus.OK); + + return new ResponseEntity< >(photoResponse, HttpStatus.OK); } @PutMapping("/{id}") @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") public ResponseEntity updatePhoto(@PathVariable(name = "id") Long id, @Valid @RequestBody PhotoRequest photoRequest, @CurrentUser UserPrincipal currentUser) { - + PhotoResponse photoResponse = photoService.updatePhoto(id, photoRequest, currentUser); - - return new ResponseEntity(photoResponse, HttpStatus.OK); + + return new ResponseEntity< >(photoResponse, HttpStatus.OK); } @DeleteMapping("/{id}") @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") public ResponseEntity deletePhoto(@PathVariable(name = "id") Long id, @CurrentUser UserPrincipal currentUser) { ApiResponse apiResponse = photoService.deletePhoto(id, currentUser); - - return new ResponseEntity(apiResponse, HttpStatus.OK); + + return new ResponseEntity< >(apiResponse, HttpStatus.OK); } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/PostController.java b/src/main/java/com/sopromadze/blogapi/controller/PostController.java index 77f3901f..5b8efcc7 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/PostController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/PostController.java @@ -1,7 +1,14 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.model.Post; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.payload.PostRequest; +import com.sopromadze.blogapi.payload.PostResponse; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.PostService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,15 +23,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.model.post.Post; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.payload.PostRequest; -import com.sopromadze.blogapi.payload.PostResponse; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.PostService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/posts") @@ -37,8 +36,8 @@ public ResponseEntity> getAllPosts( @RequestParam(value = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, @RequestParam(value = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { PagedResponse response = postService.getAllPosts(page, size); - - return new ResponseEntity>(response, HttpStatus.OK); + + return new ResponseEntity< >(response, HttpStatus.OK); } @GetMapping("/category/{id}") @@ -47,8 +46,8 @@ public ResponseEntity> getPostsByCategory( @RequestParam(value = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size, @PathVariable(name = "id") Long id) { PagedResponse response = postService.getPostsByCategory(id, page, size); - - return new ResponseEntity>(response, HttpStatus.OK); + + return new ResponseEntity< >(response, HttpStatus.OK); } @GetMapping("/tag/{id}") @@ -57,8 +56,8 @@ public ResponseEntity> getPostsByTag( @RequestParam(value = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size, @PathVariable(name = "id") Long id) { PagedResponse response = postService.getPostsByTag(id, page, size); - - return new ResponseEntity>(response, HttpStatus.OK); + + return new ResponseEntity< >(response, HttpStatus.OK); } @PostMapping @@ -66,15 +65,15 @@ public ResponseEntity> getPostsByTag( public ResponseEntity addPost(@Valid @RequestBody PostRequest postRequest, @CurrentUser UserPrincipal currentUser) { PostResponse postResponse = postService.addPost(postRequest, currentUser); - - return new ResponseEntity(postResponse, HttpStatus.CREATED); + + return new ResponseEntity< >(postResponse, HttpStatus.CREATED); } @GetMapping("/{id}") public ResponseEntity getPost(@PathVariable(name = "id") Long id) { Post post = postService.getPost(id); - - return new ResponseEntity(post, HttpStatus.OK); + + return new ResponseEntity< >(post, HttpStatus.OK); } @PutMapping("/{id}") @@ -82,15 +81,15 @@ public ResponseEntity getPost(@PathVariable(name = "id") Long id) { public ResponseEntity updatePost(@PathVariable(name = "id") Long id, @Valid @RequestBody PostRequest newPostRequest, @CurrentUser UserPrincipal currentUser) { Post post = postService.updatePost(id, newPostRequest, currentUser); - - return new ResponseEntity(post, HttpStatus.OK); + + return new ResponseEntity< >(post, HttpStatus.OK); } @DeleteMapping("/{id}") @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") public ResponseEntity deletePost(@PathVariable(name = "id") Long id, @CurrentUser UserPrincipal currentUser) { ApiResponse apiResponse = postService.deletePost(id, currentUser); - - return new ResponseEntity(apiResponse, HttpStatus.OK); + + return new ResponseEntity< >(apiResponse, HttpStatus.OK); } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/TagController.java b/src/main/java/com/sopromadze/blogapi/controller/TagController.java index e5a461c8..9a9b45c8 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/TagController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/TagController.java @@ -1,7 +1,12 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.model.Tag; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.TagService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,60 +21,54 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.model.tag.Tag; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.TagService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/tags") public class TagController { @Autowired - private TagService tagService; - - @GetMapping - public ResponseEntity> getAllTags( - @RequestParam(name = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, - @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { - - PagedResponse response = tagService.getAllTags(page, size); - - return new ResponseEntity>(response, HttpStatus.OK); - } - - @PostMapping - @PreAuthorize("hasRole('USER')") - public ResponseEntity addTag(@Valid @RequestBody Tag tag, @CurrentUser UserPrincipal currentUser){ - Tag newTag = tagService.addTag(tag, currentUser); - - return new ResponseEntity(newTag, HttpStatus.CREATED); - } - - @GetMapping("/{id}") - public ResponseEntity getTag(@PathVariable(name = "id") Long id){ - Tag tag = tagService.getTag(id); - - return new ResponseEntity(tag, HttpStatus.OK); - } - - @PutMapping("/{id}") - @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") - public ResponseEntity updateTag(@PathVariable(name = "id") Long id, @Valid @RequestBody Tag tag, @CurrentUser UserPrincipal currentUser){ - - Tag updatedTag = tagService.updateTag(id, tag, currentUser); - - return new ResponseEntity(updatedTag, HttpStatus.OK); - } - - @DeleteMapping("/{id}") - @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") - public ResponseEntity deleteTag(@PathVariable(name = "id") Long id, @CurrentUser UserPrincipal currentUser){ - ApiResponse apiResponse = tagService.deleteTag(id, currentUser); - - return new ResponseEntity(apiResponse, HttpStatus.OK); - } + private TagService tagService; + + @GetMapping + public ResponseEntity> getAllTags( + @RequestParam(name = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, + @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { + + PagedResponse response = tagService.getAllTags(page, size); + + return new ResponseEntity< >(response, HttpStatus.OK); + } + + @PostMapping + @PreAuthorize("hasRole('USER')") + public ResponseEntity addTag(@Valid @RequestBody Tag tag, @CurrentUser UserPrincipal currentUser) { + Tag newTag = tagService.addTag(tag, currentUser); + + return new ResponseEntity< >(newTag, HttpStatus.CREATED); + } + + @GetMapping("/{id}") + public ResponseEntity getTag(@PathVariable(name = "id") Long id) { + Tag tag = tagService.getTag(id); + + return new ResponseEntity< >(tag, HttpStatus.OK); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") + public ResponseEntity updateTag(@PathVariable(name = "id") Long id, @Valid @RequestBody Tag tag, @CurrentUser UserPrincipal currentUser) { + + Tag updatedTag = tagService.updateTag(id, tag, currentUser); + + return new ResponseEntity< >(updatedTag, HttpStatus.OK); + } + + @DeleteMapping("/{id}") + @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") + public ResponseEntity deleteTag(@PathVariable(name = "id") Long id, @CurrentUser UserPrincipal currentUser) { + ApiResponse apiResponse = tagService.deleteTag(id, currentUser); + + return new ResponseEntity< >(apiResponse, HttpStatus.OK); + } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/TodoController.java b/src/main/java/com/sopromadze/blogapi/controller/TodoController.java index d59f912b..ccdf91f1 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/TodoController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/TodoController.java @@ -1,7 +1,12 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.model.Todo; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.TodoService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,80 +21,75 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.model.todo.Todo; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.TodoService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/todos") public class TodoController { @Autowired - private TodoService todoService; - - @GetMapping - @PreAuthorize("hasRole('USER')") - public ResponseEntity> getAllTodos( - @CurrentUser UserPrincipal currentUser, - @RequestParam(value = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, - @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size){ - - PagedResponse response = todoService.getAllTodos(currentUser, page, size); - - return new ResponseEntity>(response, HttpStatus.OK); - } - - @PostMapping - @PreAuthorize("hasRole('USER')") - public ResponseEntity addTodo(@Valid @RequestBody Todo todo, @CurrentUser UserPrincipal currentUser){ - Todo newTodo = todoService.addTodo(todo, currentUser); - - return new ResponseEntity(newTodo, HttpStatus.CREATED); - } - - @GetMapping("/{id}") - @PreAuthorize("hasRole('USER')") - public ResponseEntity getTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser){ - Todo todo = todoService.getTodo(id, currentUser); - - return new ResponseEntity(todo, HttpStatus.OK); - } - - @PutMapping("/{id}") - @PreAuthorize("hasRole('USER')") - public ResponseEntity updateTodo(@PathVariable(value = "id") Long id, @Valid @RequestBody Todo newTodo, @CurrentUser UserPrincipal currentUser){ - Todo updatedTodo = todoService.updateTodo(id, newTodo, currentUser); - - return new ResponseEntity(updatedTodo, HttpStatus.OK); - } - - @DeleteMapping("/{id}") - @PreAuthorize("hasRole('USER')") - public ResponseEntity deleteTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser){ - ApiResponse apiResponse = todoService.deleteTodo(id, currentUser); - - return new ResponseEntity(apiResponse, HttpStatus.OK); - } - - @PutMapping("/{id}/complete") - @PreAuthorize("hasRole('USER')") - public ResponseEntity completeTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser){ - - Todo todo = todoService.completeTodo(id, currentUser); - - return new ResponseEntity(todo, HttpStatus.OK); - } - - @PutMapping("/{id}/unComplete") - @PreAuthorize("hasRole('USER')") - public ResponseEntity unCompleteTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser){ - - Todo todo = todoService.unCompleteTodo(id, currentUser); - - return new ResponseEntity(todo, HttpStatus.OK); - } + private TodoService todoService; + + @GetMapping + @PreAuthorize("hasRole('USER')") + public ResponseEntity> getAllTodos( + @CurrentUser UserPrincipal currentUser, + @RequestParam(value = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, + @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { + + PagedResponse response = todoService.getAllTodos(currentUser, page, size); + + return new ResponseEntity< >(response, HttpStatus.OK); + } + + @PostMapping + @PreAuthorize("hasRole('USER')") + public ResponseEntity addTodo(@Valid @RequestBody Todo todo, @CurrentUser UserPrincipal currentUser) { + Todo newTodo = todoService.addTodo(todo, currentUser); + + return new ResponseEntity< >(newTodo, HttpStatus.CREATED); + } + + @GetMapping("/{id}") + @PreAuthorize("hasRole('USER')") + public ResponseEntity getTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser) { + Todo todo = todoService.getTodo(id, currentUser); + + return new ResponseEntity< >(todo, HttpStatus.OK); + } + + @PutMapping("/{id}") + @PreAuthorize("hasRole('USER')") + public ResponseEntity updateTodo(@PathVariable(value = "id") Long id, @Valid @RequestBody Todo newTodo, + @CurrentUser UserPrincipal currentUser) { + Todo updatedTodo = todoService.updateTodo(id, newTodo, currentUser); + + return new ResponseEntity< >(updatedTodo, HttpStatus.OK); + } + + @DeleteMapping("/{id}") + @PreAuthorize("hasRole('USER')") + public ResponseEntity deleteTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser) { + ApiResponse apiResponse = todoService.deleteTodo(id, currentUser); + + return new ResponseEntity(apiResponse, HttpStatus.OK); + } + + @PutMapping("/{id}/complete") + @PreAuthorize("hasRole('USER')") + public ResponseEntity completeTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser) { + + Todo todo = todoService.completeTodo(id, currentUser); + + return new ResponseEntity< >(todo, HttpStatus.OK); + } + + @PutMapping("/{id}/unComplete") + @PreAuthorize("hasRole('USER')") + public ResponseEntity unCompleteTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser) { + + Todo todo = todoService.unCompleteTodo(id, currentUser); + + return new ResponseEntity< >(todo, HttpStatus.OK); + } } diff --git a/src/main/java/com/sopromadze/blogapi/controller/UserController.java b/src/main/java/com/sopromadze/blogapi/controller/UserController.java index 12085ad8..f6b717e2 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/UserController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/UserController.java @@ -1,7 +1,20 @@ package com.sopromadze.blogapi.controller; -import javax.validation.Valid; - +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.model.Post; +import com.sopromadze.blogapi.model.user.User; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.InfoRequest; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.payload.UserIdentityAvailability; +import com.sopromadze.blogapi.payload.UserProfile; +import com.sopromadze.blogapi.payload.UserSummary; +import com.sopromadze.blogapi.security.CurrentUser; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.AlbumService; +import com.sopromadze.blogapi.service.PostService; +import com.sopromadze.blogapi.service.UserService; +import com.sopromadze.blogapi.utils.AppConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -16,21 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.sopromadze.blogapi.model.album.Album; -import com.sopromadze.blogapi.model.post.Post; -import com.sopromadze.blogapi.model.user.User; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.InfoRequest; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.payload.UserIdentityAvailability; -import com.sopromadze.blogapi.payload.UserProfile; -import com.sopromadze.blogapi.payload.UserSummary; -import com.sopromadze.blogapi.security.CurrentUser; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.AlbumService; -import com.sopromadze.blogapi.service.PostService; -import com.sopromadze.blogapi.service.UserService; -import com.sopromadze.blogapi.utils.AppConstants; +import javax.validation.Valid; @RestController @RequestMapping("/api/users") @@ -48,28 +47,28 @@ public class UserController { @PreAuthorize("hasRole('USER')") public ResponseEntity getCurrentUser(@CurrentUser UserPrincipal currentUser) { UserSummary userSummary = userService.getCurrentUser(currentUser); - - return new ResponseEntity(userSummary, HttpStatus.OK); + + return new ResponseEntity< >(userSummary, HttpStatus.OK); } @GetMapping("/checkUsernameAvailability") public ResponseEntity checkUsernameAvailability(@RequestParam(value = "username") String username) { UserIdentityAvailability userIdentityAvailability = userService.checkUsernameAvailability(username); - - return new ResponseEntity(userIdentityAvailability, HttpStatus.OK); + + return new ResponseEntity< >(userIdentityAvailability, HttpStatus.OK); } @GetMapping("/checkEmailAvailability") public ResponseEntity checkEmailAvailability(@RequestParam(value = "email") String email) { - UserIdentityAvailability userIdentityAvailability = userService.checkEmailAvailability(email); - return new ResponseEntity(userIdentityAvailability, HttpStatus.OK); + UserIdentityAvailability userIdentityAvailability = userService.checkEmailAvailability(email); + return new ResponseEntity< >(userIdentityAvailability, HttpStatus.OK); } @GetMapping("/{username}/profile") public ResponseEntity getUSerProfile(@PathVariable(value = "username") String username) { UserProfile userProfile = userService.getUserProfile(username); - - return new ResponseEntity(userProfile, HttpStatus.OK); + + return new ResponseEntity< >(userProfile, HttpStatus.OK); } @GetMapping("/{username}/posts") @@ -77,8 +76,8 @@ public ResponseEntity> getPostsCreatedBy(@PathVariable(value @RequestParam(value = "page", required = false, defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) Integer page, @RequestParam(value = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { PagedResponse response = postService.getPostsByCreatedBy(username, page, size); - - return new ResponseEntity>(response, HttpStatus.OK); + + return new ResponseEntity< >(response, HttpStatus.OK); } @GetMapping("/{username}/albums") @@ -87,16 +86,16 @@ public ResponseEntity> getUserAlbums(@PathVariable(name = " @RequestParam(name = "size", required = false, defaultValue = AppConstants.DEFAULT_PAGE_SIZE) Integer size) { PagedResponse response = albumService.getUserAlbums(username, page, size); - - return new ResponseEntity>(response, HttpStatus.OK); + + return new ResponseEntity< >(response, HttpStatus.OK); } @PostMapping @PreAuthorize("hasRole('ADMIN')") public ResponseEntity addUser(@Valid @RequestBody User user) { User newUser = userService.addUser(user); - - return new ResponseEntity(newUser, HttpStatus.CREATED); + + return new ResponseEntity< >(newUser, HttpStatus.CREATED); } @PutMapping("/{username}") @@ -104,8 +103,8 @@ public ResponseEntity addUser(@Valid @RequestBody User user) { public ResponseEntity updateUser(@Valid @RequestBody User newUser, @PathVariable(value = "username") String username, @CurrentUser UserPrincipal currentUser) { User updatedUSer = userService.updateUser(newUser, username, currentUser); - - return new ResponseEntity(updatedUSer, HttpStatus.CREATED); + + return new ResponseEntity< >(updatedUSer, HttpStatus.CREATED); } @DeleteMapping("/{username}") @@ -113,24 +112,24 @@ public ResponseEntity updateUser(@Valid @RequestBody User newUser, public ResponseEntity deleteUser(@PathVariable(value = "username") String username, @CurrentUser UserPrincipal currentUser) { ApiResponse apiResponse = userService.deleteUser(username, currentUser); - - return new ResponseEntity(apiResponse, HttpStatus.OK); + + return new ResponseEntity< >(apiResponse, HttpStatus.OK); } @PutMapping("/{username}/giveAdmin") @PreAuthorize("hasRole('ADMIN')") public ResponseEntity giveAdmin(@PathVariable(name = "username") String username) { ApiResponse apiResponse = userService.giveAdmin(username); - - return new ResponseEntity(apiResponse, HttpStatus.OK); + + return new ResponseEntity< >(apiResponse, HttpStatus.OK); } @PutMapping("/{username}/takeAdmin") @PreAuthorize("hasRole('ADMIN')") public ResponseEntity takeAdmin(@PathVariable(name = "username") String username) { ApiResponse apiResponse = userService.removeAdmin(username); - - return new ResponseEntity(apiResponse, HttpStatus.OK); + + return new ResponseEntity< >(apiResponse, HttpStatus.OK); } @PutMapping("/setOrUpdateInfo") @@ -138,8 +137,8 @@ public ResponseEntity takeAdmin(@PathVariable(name = "username") St public ResponseEntity setAddress(@CurrentUser UserPrincipal currentUser, @Valid @RequestBody InfoRequest infoRequest) { UserProfile userProfile = userService.setOrUpdateInfo(currentUser, infoRequest); - - return new ResponseEntity(userProfile, HttpStatus.OK); + + return new ResponseEntity< >(userProfile, HttpStatus.OK); } } diff --git a/src/main/java/com/sopromadze/blogapi/exception/AccessDeniedException.java b/src/main/java/com/sopromadze/blogapi/exception/AccessDeniedException.java index 55951ac7..ba5391e1 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/AccessDeniedException.java +++ b/src/main/java/com/sopromadze/blogapi/exception/AccessDeniedException.java @@ -1,29 +1,28 @@ package com.sopromadze.blogapi.exception; +import com.sopromadze.blogapi.payload.ApiResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -import com.sopromadze.blogapi.payload.ApiResponse; - @ResponseStatus(code = HttpStatus.UNAUTHORIZED) public class AccessDeniedException extends RuntimeException { private static final long serialVersionUID = 1L; - + private ApiResponse apiResponse; private String message; - + public AccessDeniedException(ApiResponse apiResponse) { super(); this.apiResponse = apiResponse; } - public AccessDeniedException(String message){ + public AccessDeniedException(String message) { super(message); this.message = message; } - - public AccessDeniedException(String message, Throwable cause){ + + public AccessDeniedException(String message, Throwable cause) { super(message, cause); } diff --git a/src/main/java/com/sopromadze/blogapi/exception/BadRequestException.java b/src/main/java/com/sopromadze/blogapi/exception/BadRequestException.java index 3f862a22..a35149fe 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/BadRequestException.java +++ b/src/main/java/com/sopromadze/blogapi/exception/BadRequestException.java @@ -1,16 +1,15 @@ package com.sopromadze.blogapi.exception; +import com.sopromadze.blogapi.payload.ApiResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -import com.sopromadze.blogapi.payload.ApiResponse; - @ResponseStatus(HttpStatus.BAD_REQUEST) public class BadRequestException extends RuntimeException { private static final long serialVersionUID = 1L; - + private ApiResponse apiResponse; - + public BadRequestException(ApiResponse apiResponse) { super(); this.apiResponse = apiResponse; @@ -23,7 +22,7 @@ public BadRequestException(String message) { public BadRequestException(String message, Throwable cause) { super(message, cause); } - + public ApiResponse getApiResponse() { return apiResponse; } diff --git a/src/main/java/com/sopromadze/blogapi/exception/BlogapiException.java b/src/main/java/com/sopromadze/blogapi/exception/BlogapiException.java index ba6f9523..4da4fd63 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/BlogapiException.java +++ b/src/main/java/com/sopromadze/blogapi/exception/BlogapiException.java @@ -5,16 +5,16 @@ public class BlogapiException extends RuntimeException { private static final long serialVersionUID = -6593330219878485669L; - + private final HttpStatus status; private final String message; - + public BlogapiException(HttpStatus status, String message) { super(); this.status = status; this.message = message; } - + public BlogapiException(HttpStatus status, String message, Throwable exception) { super(exception); this.status = status; @@ -24,7 +24,7 @@ public BlogapiException(HttpStatus status, String message, Throwable exception) public HttpStatus getStatus() { return status; } - + public String getMessage() { return message; } diff --git a/src/main/java/com/sopromadze/blogapi/exception/ResourceNotFoundException.java b/src/main/java/com/sopromadze/blogapi/exception/ResourceNotFoundException.java index c9c5fb75..4dd90e07 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/ResourceNotFoundException.java +++ b/src/main/java/com/sopromadze/blogapi/exception/ResourceNotFoundException.java @@ -1,14 +1,13 @@ package com.sopromadze.blogapi.exception; +import com.sopromadze.blogapi.payload.ApiResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -import com.sopromadze.blogapi.payload.ApiResponse; - @ResponseStatus(value = HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException { private static final long serialVersionUID = 1L; - + private transient ApiResponse apiResponse; private String resourceName; @@ -37,10 +36,10 @@ public Object getFieldValue() { public ApiResponse getApiResponse() { return apiResponse; } - + private void setApiResponse() { String message = String.format("%s not found with %s: '%s'", resourceName, fieldName, fieldValue); - + apiResponse = new ApiResponse(Boolean.FALSE, message); } } diff --git a/src/main/java/com/sopromadze/blogapi/exception/ResponseEntityErrorException.java b/src/main/java/com/sopromadze/blogapi/exception/ResponseEntityErrorException.java index ec51d833..f5aeaaed 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/ResponseEntityErrorException.java +++ b/src/main/java/com/sopromadze/blogapi/exception/ResponseEntityErrorException.java @@ -1,14 +1,13 @@ package com.sopromadze.blogapi.exception; -import org.springframework.http.ResponseEntity; - import com.sopromadze.blogapi.payload.ApiResponse; +import org.springframework.http.ResponseEntity; public class ResponseEntityErrorException extends RuntimeException { private static final long serialVersionUID = -3156815846745801694L; - + private transient ResponseEntity apiResponse; - + public ResponseEntityErrorException(ResponseEntity apiResponse) { this.apiResponse = apiResponse; } diff --git a/src/main/java/com/sopromadze/blogapi/exception/RestControllerExceptionHandler.java b/src/main/java/com/sopromadze/blogapi/exception/RestControllerExceptionHandler.java index 9cbeadfb..a9372e45 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/RestControllerExceptionHandler.java +++ b/src/main/java/com/sopromadze/blogapi/exception/RestControllerExceptionHandler.java @@ -1,9 +1,7 @@ package com.sopromadze.blogapi.exception; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.ExceptionResponse; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -16,57 +14,57 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.ExceptionResponse; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; @ControllerAdvice public class RestControllerExceptionHandler { - - public ResponseEntity resolveException(BlogapiException exception){ + + public ResponseEntity resolveException(BlogapiException exception) { String message = exception.getMessage(); HttpStatus status = exception.getStatus(); - + ApiResponse apiResponse = new ApiResponse(); - + apiResponse.setSuccess(Boolean.FALSE); apiResponse.setMessage(message); - + return new ResponseEntity<>(apiResponse, status); } - + @ExceptionHandler(UnauthorizedException.class) @ResponseBody @ResponseStatus(code = HttpStatus.UNAUTHORIZED) - public ResponseEntity resolveException(UnauthorizedException exception){ - + public ResponseEntity resolveException(UnauthorizedException exception) { + ApiResponse apiResponse = exception.getApiResponse(); - + return new ResponseEntity<>(apiResponse, HttpStatus.UNAUTHORIZED); } - + @ExceptionHandler(BadRequestException.class) @ResponseBody - public ResponseEntity resolveException(BadRequestException exception){ + public ResponseEntity resolveException(BadRequestException exception) { ApiResponse apiResponse = exception.getApiResponse(); - - return new ResponseEntity(apiResponse, HttpStatus.BAD_REQUEST); + + return new ResponseEntity<>(apiResponse, HttpStatus.BAD_REQUEST); } - - + @ExceptionHandler(ResourceNotFoundException.class) @ResponseBody - public ResponseEntity resolveException(ResourceNotFoundException exception){ + public ResponseEntity resolveException(ResourceNotFoundException exception) { ApiResponse apiResponse = exception.getApiResponse(); - - return new ResponseEntity(apiResponse, HttpStatus.NOT_FOUND); + + return new ResponseEntity<>(apiResponse, HttpStatus.NOT_FOUND); } - + @ExceptionHandler(AccessDeniedException.class) @ResponseBody - public ResponseEntity resolveException(AccessDeniedException exception){ + public ResponseEntity resolveException(AccessDeniedException exception) { ApiResponse apiResponse = exception.getApiResponse(); - - return new ResponseEntity(apiResponse, HttpStatus.FORBIDDEN); + + return new ResponseEntity< >(apiResponse, HttpStatus.FORBIDDEN); } @ExceptionHandler({ MethodArgumentNotValidException.class }) @@ -102,7 +100,7 @@ public ResponseEntity resolveException(HttpRequestMethodNotSu + ex.getSupportedHttpMethods(); List messages = new ArrayList<>(1); messages.add(message); - + return new ResponseEntity<>(new ExceptionResponse(messages, HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase(), HttpStatus.METHOD_NOT_ALLOWED.value()), HttpStatus.METHOD_NOT_ALLOWED); } diff --git a/src/main/java/com/sopromadze/blogapi/exception/UnauthorizedException.java b/src/main/java/com/sopromadze/blogapi/exception/UnauthorizedException.java index f6de4522..1760c66b 100644 --- a/src/main/java/com/sopromadze/blogapi/exception/UnauthorizedException.java +++ b/src/main/java/com/sopromadze/blogapi/exception/UnauthorizedException.java @@ -1,29 +1,28 @@ package com.sopromadze.blogapi.exception; +import com.sopromadze.blogapi.payload.ApiResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -import com.sopromadze.blogapi.payload.ApiResponse; - @ResponseStatus(code = HttpStatus.UNAUTHORIZED) public class UnauthorizedException extends RuntimeException { private static final long serialVersionUID = 1L; - + private ApiResponse apiResponse; private String message; - + public UnauthorizedException(ApiResponse apiResponse) { super(); this.apiResponse = apiResponse; } - public UnauthorizedException(String message){ + public UnauthorizedException(String message) { super(message); this.message = message; } - - public UnauthorizedException(String message, Throwable cause){ + + public UnauthorizedException(String message, Throwable cause) { super(message, cause); } diff --git a/src/main/java/com/sopromadze/blogapi/model/album/Album.java b/src/main/java/com/sopromadze/blogapi/model/Album.java similarity index 81% rename from src/main/java/com/sopromadze/blogapi/model/album/Album.java rename to src/main/java/com/sopromadze/blogapi/model/Album.java index 56a628f5..72841c7c 100644 --- a/src/main/java/com/sopromadze/blogapi/model/album/Album.java +++ b/src/main/java/com/sopromadze/blogapi/model/Album.java @@ -1,8 +1,9 @@ -package com.sopromadze.blogapi.model.album; +package com.sopromadze.blogapi.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import com.sopromadze.blogapi.model.user.User; +import lombok.Data; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -17,13 +18,12 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; import javax.validation.constraints.NotBlank; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; -import com.sopromadze.blogapi.model.photo.Photo; -import com.sopromadze.blogapi.model.user.User; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; @Entity +@Data @Table(name = "albums", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) public class Album extends UserDateAudit { private static final long serialVersionUID = 1L; @@ -43,31 +43,11 @@ public class Album extends UserDateAudit { @OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true) private List photo; - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - @JsonIgnore public User getUser() { return user; } - public void setUser(User user) { - this.user = user; - } - public List getPhoto() { return this.photo == null ? null : new ArrayList<>(this.photo); } diff --git a/src/main/java/com/sopromadze/blogapi/model/category/Category.java b/src/main/java/com/sopromadze/blogapi/model/Category.java similarity index 77% rename from src/main/java/com/sopromadze/blogapi/model/category/Category.java rename to src/main/java/com/sopromadze/blogapi/model/Category.java index 58451985..9d2358c1 100644 --- a/src/main/java/com/sopromadze/blogapi/model/category/Category.java +++ b/src/main/java/com/sopromadze/blogapi/model/Category.java @@ -1,8 +1,10 @@ -package com.sopromadze.blogapi.model.category; +package com.sopromadze.blogapi.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -12,53 +14,33 @@ import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; - -import com.fasterxml.jackson.annotation.JsonIdentityInfo; -import com.fasterxml.jackson.annotation.ObjectIdGenerators; -import com.sopromadze.blogapi.model.audit.UserDateAudit; -import com.sopromadze.blogapi.model.post.Post; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; @Entity +@Data +@NoArgsConstructor @Table(name = "categories") @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") -public class Category extends UserDateAudit{ +public class Category extends UserDateAudit { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - + @Column(name = "name") private String name; - + @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true) private List posts; - public Category() { - - } - public Category(String name) { super(); this.name = name; } - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - public List getPosts() { return this.posts == null ? null : new ArrayList<>(this.posts); } diff --git a/src/main/java/com/sopromadze/blogapi/model/Comment.java b/src/main/java/com/sopromadze/blogapi/model/Comment.java new file mode 100644 index 00000000..4b790c5a --- /dev/null +++ b/src/main/java/com/sopromadze/blogapi/model/Comment.java @@ -0,0 +1,70 @@ +package com.sopromadze.blogapi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import com.sopromadze.blogapi.model.user.User; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +@Entity +@Data +@NoArgsConstructor +@Table(name = "comments") +public class Comment extends UserDateAudit { + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name") + @NotBlank + @Size(min = 4, max = 50) + private String name; + + @Column(name = "email") + @NotBlank + @Email + @Size(min = 4, max = 50) + private String email; + + @Column(name = "body") + @NotBlank + @Size(min = 10, message = "Comment body must be minimum 10 characters") + private String body; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + public Comment(@NotBlank @Size(min = 10, message = "Comment body must be minimum 10 characters") String body) { + this.body = body; + } + + @JsonIgnore + public Post getPost() { + return post; + } + + @JsonIgnore + public User getUser() { + return user; + } +} diff --git a/src/main/java/com/sopromadze/blogapi/model/photo/Photo.java b/src/main/java/com/sopromadze/blogapi/model/Photo.java similarity index 67% rename from src/main/java/com/sopromadze/blogapi/model/photo/Photo.java rename to src/main/java/com/sopromadze/blogapi/model/Photo.java index 48ae0ee4..c65f6bff 100644 --- a/src/main/java/com/sopromadze/blogapi/model/photo/Photo.java +++ b/src/main/java/com/sopromadze/blogapi/model/Photo.java @@ -1,4 +1,10 @@ -package com.sopromadze.blogapi.model.photo; +package com.sopromadze.blogapi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.Column; import javax.persistence.Entity; @@ -12,11 +18,9 @@ import javax.persistence.UniqueConstraint; import javax.validation.constraints.NotBlank; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.album.Album; -import com.sopromadze.blogapi.model.audit.UserDateAudit; - @Entity +@Data +@NoArgsConstructor @Table(name = "photos", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) public class Photo extends UserDateAudit { private static final long serialVersionUID = 1L; @@ -41,10 +45,6 @@ public class Photo extends UserDateAudit { @JoinColumn(name = "album_id") private Album album; - public Photo() { - - } - public Photo(@NotBlank String title, @NotBlank String url, @NotBlank String thumbnailUrl, Album album) { this.title = title; this.url = url; @@ -52,44 +52,8 @@ public Photo(@NotBlank String title, @NotBlank String url, @NotBlank String thum this.album = album; } - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getThumbnailUrl() { - return thumbnailUrl; - } - - public void setThumbnailUrl(String thumbnailUrl) { - this.thumbnailUrl = thumbnailUrl; - } - @JsonIgnore public Album getAlbum() { return album; } - - public void setAlbum(Album album) { - this.album = album; - } } diff --git a/src/main/java/com/sopromadze/blogapi/model/post/Post.java b/src/main/java/com/sopromadze/blogapi/model/Post.java similarity index 79% rename from src/main/java/com/sopromadze/blogapi/model/post/Post.java rename to src/main/java/com/sopromadze/blogapi/model/Post.java index 369c6b65..c654a58f 100644 --- a/src/main/java/com/sopromadze/blogapi/model/post/Post.java +++ b/src/main/java/com/sopromadze/blogapi/model/Post.java @@ -1,8 +1,11 @@ -package com.sopromadze.blogapi.model.post; +package com.sopromadze.blogapi.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import com.sopromadze.blogapi.model.user.User; +import lombok.Data; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -18,17 +21,12 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; - -import com.fasterxml.jackson.annotation.JsonIdentityInfo; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.ObjectIdGenerators; -import com.sopromadze.blogapi.model.audit.UserDateAudit; -import com.sopromadze.blogapi.model.category.Category; -import com.sopromadze.blogapi.model.comment.Comment; -import com.sopromadze.blogapi.model.tag.Tag; -import com.sopromadze.blogapi.model.user.User; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; @Entity +@Data @Table(name = "posts", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Post extends UserDateAudit { @@ -60,30 +58,6 @@ public class Post extends UserDateAudit { @JoinTable(name = "post_tag", joinColumns = @JoinColumn(name = "post_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id")) private List tags; - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - @JsonIgnore public User getUser() { return user; @@ -105,14 +79,6 @@ public void setComments(List comments) { } } - public Category getCategory() { - return category; - } - - public void setCategory(Category category) { - this.category = category; - } - public List getTags() { return tags == null ? null : new ArrayList<>(tags); } diff --git a/src/main/java/com/sopromadze/blogapi/model/tag/Tag.java b/src/main/java/com/sopromadze/blogapi/model/Tag.java similarity index 82% rename from src/main/java/com/sopromadze/blogapi/model/tag/Tag.java rename to src/main/java/com/sopromadze/blogapi/model/Tag.java index 5b69208a..a7b64ccd 100644 --- a/src/main/java/com/sopromadze/blogapi/model/tag/Tag.java +++ b/src/main/java/com/sopromadze/blogapi/model/Tag.java @@ -1,8 +1,10 @@ -package com.sopromadze.blogapi.model.tag; +package com.sopromadze.blogapi.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import com.sopromadze.blogapi.model.Post; +import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.Column; import javax.persistence.Entity; @@ -14,12 +16,13 @@ import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; -import com.sopromadze.blogapi.model.post.Post; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; @Entity +@Data +@NoArgsConstructor @Table(name = "tags") //@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Tag extends UserDateAudit { @@ -38,31 +41,11 @@ public class Tag extends UserDateAudit { @JoinTable(name = "post_tag", joinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "post_id", referencedColumnName = "id")) private List posts; - public Tag() { - - } - public Tag(String name) { super(); this.name = name; } - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - public List getPosts() { return posts == null ? null : new ArrayList<>(posts); } diff --git a/src/main/java/com/sopromadze/blogapi/model/todo/Todo.java b/src/main/java/com/sopromadze/blogapi/model/Todo.java similarity index 71% rename from src/main/java/com/sopromadze/blogapi/model/todo/Todo.java rename to src/main/java/com/sopromadze/blogapi/model/Todo.java index d5c3559e..06840c1c 100644 --- a/src/main/java/com/sopromadze/blogapi/model/todo/Todo.java +++ b/src/main/java/com/sopromadze/blogapi/model/Todo.java @@ -1,4 +1,9 @@ -package com.sopromadze.blogapi.model.todo; +package com.sopromadze.blogapi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import com.sopromadze.blogapi.model.user.User; +import lombok.Data; import javax.persistence.Column; import javax.persistence.Entity; @@ -12,11 +17,8 @@ import javax.persistence.UniqueConstraint; import javax.validation.constraints.NotBlank; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; -import com.sopromadze.blogapi.model.user.User; - @Entity +@Data @Table(name = "todos", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) public class Todo extends UserDateAudit { @@ -37,36 +39,8 @@ public class Todo extends UserDateAudit { @JoinColumn(name = "user_id") private User user; - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Boolean getCompleted() { - return completed; - } - - public void setCompleted(Boolean completed) { - this.completed = completed; - } - @JsonIgnore public User getUser() { return user; } - - public void setUser(User user) { - this.user = user; - } } diff --git a/src/main/java/com/sopromadze/blogapi/model/audit/DateAudit.java b/src/main/java/com/sopromadze/blogapi/model/audit/DateAudit.java index 63b2fac4..c9f8abe7 100644 --- a/src/main/java/com/sopromadze/blogapi/model/audit/DateAudit.java +++ b/src/main/java/com/sopromadze/blogapi/model/audit/DateAudit.java @@ -1,6 +1,7 @@ package com.sopromadze.blogapi.model.audit; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -12,36 +13,22 @@ import java.time.Instant; @MappedSuperclass +@Data @EntityListeners(AuditingEntityListener.class) @JsonIgnoreProperties( - value = {"createdAt", "updatedAt"}, - allowGetters = true + value = { "createdAt", "updatedAt" }, + allowGetters = true ) public abstract class DateAudit implements Serializable { private static final long serialVersionUID = 1L; @CreatedDate - @Column(nullable = false, updatable = false) - private Instant createdAt; + @Column(nullable = false, updatable = false) + private Instant createdAt; - @LastModifiedDate - @Column(nullable = false) - private Instant updatedAt; + @LastModifiedDate + @Column(nullable = false) + private Instant updatedAt; - public Instant getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Instant createdAt) { - this.createdAt = createdAt; - } - - public Instant getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Instant updatedAt) { - this.updatedAt = updatedAt; - } } diff --git a/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java b/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java index f1f72bf1..245bcf96 100644 --- a/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java +++ b/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java @@ -1,6 +1,7 @@ package com.sopromadze.blogapi.model.audit; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.LastModifiedBy; @@ -8,33 +9,18 @@ import javax.persistence.MappedSuperclass; @MappedSuperclass +@Data @JsonIgnoreProperties( - value = {"createdBY", "updatedBy"}, - allowGetters = true + value = { "createdBY", "updatedBy" }, + allowGetters = true ) -public abstract class UserDateAudit extends DateAudit{ +public abstract class UserDateAudit extends DateAudit { private static final long serialVersionUID = 1L; @CreatedBy - @Column(updatable = false) - private Long createdBy; + @Column(updatable = false) + private Long createdBy; - @LastModifiedBy - private Long updatedBy; - - public Long getCreatedBy() { - return createdBy; - } - - public void setCreatedBy(Long createdBy) { - this.createdBy = createdBy; - } - - public Long getUpdatedBy() { - return updatedBy; - } - - public void setUpdatedBy(Long updatedBy) { - this.updatedBy = updatedBy; - } + @LastModifiedBy + private Long updatedBy; } diff --git a/src/main/java/com/sopromadze/blogapi/model/comment/Comment.java b/src/main/java/com/sopromadze/blogapi/model/comment/Comment.java deleted file mode 100644 index 1e7d2fa5..00000000 --- a/src/main/java/com/sopromadze/blogapi/model/comment/Comment.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.sopromadze.blogapi.model.comment; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; -import com.sopromadze.blogapi.model.post.Post; -import com.sopromadze.blogapi.model.user.User; - -@Entity -@Table(name = "comments") -public class Comment extends UserDateAudit { - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "name") - @NotBlank - @Size(min = 4, max = 50) - private String name; - - @Column(name = "email") - @NotBlank - @Email - @Size(min = 4, max = 50) - private String email; - - @Column(name = "body") - @NotBlank - @Size(min = 10, message = "Comment body must be minimum 10 characters") - private String body; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; - - public Comment(){ - - } - - public Comment(@NotBlank @Size(min = 10, message = "Comment body must be minimum 10 characters") String body) { - this.body = body; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - @JsonIgnore - public Post getPost() { - return post; - } - - public void setPost(Post post) { - this.post = post; - } - - @JsonIgnore - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } -} diff --git a/src/main/java/com/sopromadze/blogapi/model/role/Role.java b/src/main/java/com/sopromadze/blogapi/model/role/Role.java index dd4b716d..00231ca9 100644 --- a/src/main/java/com/sopromadze/blogapi/model/role/Role.java +++ b/src/main/java/com/sopromadze/blogapi/model/role/Role.java @@ -1,42 +1,33 @@ package com.sopromadze.blogapi.model.role; +import lombok.Data; +import lombok.NoArgsConstructor; import org.hibernate.annotations.NaturalId; -import javax.persistence.*; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; @Entity +@Data +@NoArgsConstructor @Table(name = "roles") public class Role { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Enumerated(EnumType.STRING) - @NaturalId - @Column(name = "name") - private RoleName name; - - public Role(){ - - } - - public Role(RoleName name) { - this.name = name; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public RoleName getName() { - return name; - } - - public void setName(RoleName name) { - this.name = name; - } + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Enumerated(EnumType.STRING) + @NaturalId + @Column(name = "name") + private RoleName name; + + public Role(RoleName name) { + this.name = name; + } } diff --git a/src/main/java/com/sopromadze/blogapi/model/role/RoleName.java b/src/main/java/com/sopromadze/blogapi/model/role/RoleName.java index ae05926c..f2064b2f 100644 --- a/src/main/java/com/sopromadze/blogapi/model/role/RoleName.java +++ b/src/main/java/com/sopromadze/blogapi/model/role/RoleName.java @@ -1,6 +1,6 @@ package com.sopromadze.blogapi.model.role; public enum RoleName { - ROLE_ADMIN, - ROLE_USER, + ROLE_ADMIN, + ROLE_USER, } diff --git a/src/main/java/com/sopromadze/blogapi/model/user/Address.java b/src/main/java/com/sopromadze/blogapi/model/user/Address.java index 6c9ec73c..6c460d35 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/Address.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/Address.java @@ -1,6 +1,10 @@ package com.sopromadze.blogapi.model.user; -import java.time.Instant; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -11,11 +15,11 @@ import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; +import java.time.Instant; @Entity +@Data +@NoArgsConstructor @Table(name = "address") public class Address extends UserDateAudit { private static final long serialVersionUID = 1L; @@ -43,10 +47,6 @@ public class Address extends UserDateAudit { @OneToOne(mappedBy = "address") private User user; - public Address() { - - } - public Address(String street, String suite, String city, String zipcode, Geo geo) { this.street = street; this.suite = suite; @@ -55,55 +55,11 @@ public Address(String street, String suite, String city, String zipcode, Geo geo this.geo = geo; } - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - - public String getSuite() { - return suite; - } - - public void setSuite(String suite) { - this.suite = suite; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getZipcode() { - return zipcode; - } - - public void setZipcode(String zipcode) { - this.zipcode = zipcode; - } - @JsonIgnore public Long getId() { return id; } - public void setId(Long id) { - this.id = id; - } - - public Geo getGeo() { - return geo; - } - - public void setGeo(Geo geo) { - this.geo = geo; - } - @JsonIgnore @Override public Long getCreatedBy() { diff --git a/src/main/java/com/sopromadze/blogapi/model/user/Company.java b/src/main/java/com/sopromadze/blogapi/model/user/Company.java index fbd8a059..541d1073 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/Company.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/Company.java @@ -1,6 +1,9 @@ package com.sopromadze.blogapi.model.user; -import java.time.Instant; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.Column; import javax.persistence.Entity; @@ -9,11 +12,11 @@ import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; +import java.time.Instant; @Entity +@Data +@NoArgsConstructor @Table(name = "company") public class Company extends UserDateAudit { private static final long serialVersionUID = 1L; @@ -34,9 +37,6 @@ public class Company extends UserDateAudit { @OneToOne(mappedBy = "company") private User user; - public Company() { - - } public Company(String name, String catchPhrase, String bs) { this.name = name; @@ -44,30 +44,6 @@ public Company(String name, String catchPhrase, String bs) { this.bs = bs; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getCatchPhrase() { - return catchPhrase; - } - - public void setCatchPhrase(String catchPhrase) { - this.catchPhrase = catchPhrase; - } - - public String getBs() { - return bs; - } - - public void setBs(String bs) { - this.bs = bs; - } - @JsonIgnore public Long getId() { return id; diff --git a/src/main/java/com/sopromadze/blogapi/model/user/Geo.java b/src/main/java/com/sopromadze/blogapi/model/user/Geo.java index ed402caa..e7cfaad9 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/Geo.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/Geo.java @@ -1,6 +1,9 @@ package com.sopromadze.blogapi.model.user; -import java.time.Instant; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.audit.UserDateAudit; +import lombok.Data; +import lombok.NoArgsConstructor; import javax.persistence.Column; import javax.persistence.Entity; @@ -9,11 +12,11 @@ import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.audit.UserDateAudit; +import java.time.Instant; @Entity +@Data +@NoArgsConstructor @Table(name = "geo") public class Geo extends UserDateAudit { private static final long serialVersionUID = 1L; @@ -32,39 +35,11 @@ public class Geo extends UserDateAudit { @OneToOne(mappedBy = "geo") private Address address; - public Geo() { - - } - public Geo(String lat, String lng) { this.lat = lat; this.lng = lng; } - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - @JsonIgnore @Override public Long getCreatedBy() { diff --git a/src/main/java/com/sopromadze/blogapi/model/user/User.java b/src/main/java/com/sopromadze/blogapi/model/user/User.java index 46f5a79e..81ff6287 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/User.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/User.java @@ -1,8 +1,16 @@ package com.sopromadze.blogapi.model.user; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.model.audit.DateAudit; +import com.sopromadze.blogapi.model.Comment; +import com.sopromadze.blogapi.model.Post; +import com.sopromadze.blogapi.model.role.Role; +import com.sopromadze.blogapi.model.Todo; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.NaturalId; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -21,19 +29,13 @@ import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; - -import org.hibernate.annotations.NaturalId; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.sopromadze.blogapi.model.album.Album; -import com.sopromadze.blogapi.model.audit.DateAudit; -import com.sopromadze.blogapi.model.comment.Comment; -import com.sopromadze.blogapi.model.post.Post; -import com.sopromadze.blogapi.model.role.Role; -import com.sopromadze.blogapi.model.todo.Todo; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; @Entity +@Data +@NoArgsConstructor @Table(name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = { "username" }), @UniqueConstraint(columnNames = { "email" }) }) public class User extends DateAudit { @@ -106,10 +108,6 @@ public class User extends DateAudit { @JoinColumn(name = "company_id") private Company company; - public User() { - - } - public User(String firstName, String lastName, String username, String email, String password) { this.firstName = firstName; this.lastName = lastName; @@ -118,69 +116,15 @@ public User(String firstName, String lastName, String username, String email, St this.password = password; } - public Long getId() { - return id; - } - public void setId(Long id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Address getAddress() { - return address; - } - - public void setAddress(Address address) { - this.address = address; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public String getWebsite() { - return website; - } - - public void setWebsite(String website) { - this.website = website; - } - - public Company getCompany() { - return company; - } - - public void setCompany(Company company) { - this.company = company; - } public List getTodos() { - + return todos == null ? null : new ArrayList<>(todos); } public void setTodos(List todos) { - + if (todos == null) { this.todos = null; } else { @@ -189,12 +133,12 @@ public void setTodos(List todos) { } public List getAlbums() { - + return albums == null ? null : new ArrayList<>(albums); } public void setAlbums(List albums) { - + if (albums == null) { this.albums = null; } else { @@ -202,37 +146,14 @@ public void setAlbums(List albums) { } } - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } public List getPosts() { - + return posts == null ? null : new ArrayList<>(posts); } public void setPosts(List posts) { - + if (posts == null) { this.posts = null; } else { diff --git a/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java b/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java index 81eaf533..bd408037 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java @@ -1,14 +1,16 @@ package com.sopromadze.blogapi.payload; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.sopromadze.blogapi.model.photo.Photo; +import com.sopromadze.blogapi.model.Photo; import com.sopromadze.blogapi.model.user.User; +import lombok.Data; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Data @JsonInclude(Include.NON_NULL) public class AlbumResponse extends UserDateAuditPayload { private Long id; @@ -19,37 +21,13 @@ public class AlbumResponse extends UserDateAuditPayload { private List photo; - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - public List getPhoto() { - + return photo == null ? null : new ArrayList<>(photo); } public void setPhoto(List photo) { - + if (photo == null) { this.photo = null; } else { diff --git a/src/main/java/com/sopromadze/blogapi/payload/ApiResponse.java b/src/main/java/com/sopromadze/blogapi/payload/ApiResponse.java index 28e64390..4dfa14ab 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/ApiResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/ApiResponse.java @@ -1,67 +1,44 @@ package com.sopromadze.blogapi.payload; -import java.io.Serializable; - -import org.springframework.http.HttpStatus; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.Data; +import org.springframework.http.HttpStatus; + +import java.io.Serializable; +@Data @JsonPropertyOrder({ - "success", - "message" + "success", + "message" }) public class ApiResponse implements Serializable { - + @JsonIgnore private static final long serialVersionUID = 7702134516418120340L; - + @JsonProperty("success") private Boolean success; - + @JsonProperty("message") - private String message; - + private String message; + @JsonIgnore private HttpStatus status; - - public ApiResponse() { - - } - - public ApiResponse(Boolean success, String message) { - this.success = success; - this.message = message; - } - - public ApiResponse(Boolean success, String message, HttpStatus httpStatus) { - this.success = success; - this.message = message; - this.status = httpStatus; - } - public Boolean getSuccess() { - return success; - } + public ApiResponse() { - public void setSuccess(Boolean success) { - this.success = success; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } + } - public HttpStatus getStatus() { - return status; + public ApiResponse(Boolean success, String message) { + this.success = success; + this.message = message; } - public void setStatus(HttpStatus status) { - this.status = status; + public ApiResponse(Boolean success, String message, HttpStatus httpStatus) { + this.success = success; + this.message = message; + this.status = httpStatus; } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/CommentRequest.java b/src/main/java/com/sopromadze/blogapi/payload/CommentRequest.java index cf1b95c6..c88239ff 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/CommentRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/CommentRequest.java @@ -1,18 +1,13 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; +@Data public class CommentRequest { - @NotBlank - @Size(min = 10, message = "Comment body must be minimum 10 characters") - private String body; - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } + @NotBlank + @Size(min = 10, message = "Comment body must be minimum 10 characters") + private String body; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/DateAuditPayload.java b/src/main/java/com/sopromadze/blogapi/payload/DateAuditPayload.java index 07926ae8..7ec74a5a 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/DateAuditPayload.java +++ b/src/main/java/com/sopromadze/blogapi/payload/DateAuditPayload.java @@ -4,23 +4,23 @@ public abstract class DateAuditPayload { - private Instant createdAt; + private Instant createdAt; - private Instant updatedAt; + private Instant updatedAt; - public Instant getCreatedAt() { - return createdAt; - } + public Instant getCreatedAt() { + return createdAt; + } - public void setCreatedAt(Instant createdAt) { - this.createdAt = createdAt; - } + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } - public Instant getUpdatedAt() { - return updatedAt; - } + public Instant getUpdatedAt() { + return updatedAt; + } - public void setUpdatedAt(Instant updatedAt) { - this.updatedAt = updatedAt; - } + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/ExceptionResponse.java b/src/main/java/com/sopromadze/blogapi/payload/ExceptionResponse.java index f4c4a168..a243981b 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/ExceptionResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/ExceptionResponse.java @@ -1,58 +1,38 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.List; +@Data public class ExceptionResponse { - private String error; - private Integer status; - private List messages; - private Instant timestamp; + private String error; + private Integer status; + private List messages; + private Instant timestamp; - public ExceptionResponse(List messages, String error, Integer status) { + public ExceptionResponse(List messages, String error, Integer status) { setMessages(messages); - this.error = error; - this.status = status; - this.timestamp = Instant.now(); - } + this.error = error; + this.status = status; + this.timestamp = Instant.now(); + } + + public List getMessages() { - public List getMessages() { - return messages == null ? null : new ArrayList<>(messages); - } + } + + public final void setMessages(List messages) { - public final void setMessages(List messages) { - if (messages == null) { this.messages = null; } else { this.messages = Collections.unmodifiableList(messages); } - } - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - - public Integer getStatus() { - return status; - } - - public void setStatus(Integer status) { - this.status = status; - } - - public Instant getTimestamp() { - return timestamp; - } + } - public void setTimestamp(Instant timestamp) { - this.timestamp = timestamp; - } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/InfoRequest.java b/src/main/java/com/sopromadze/blogapi/payload/InfoRequest.java index 5417bbe2..7baf210f 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/InfoRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/InfoRequest.java @@ -1,7 +1,10 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import javax.validation.constraints.NotBlank; +@Data public class InfoRequest { @NotBlank @@ -29,92 +32,4 @@ public class InfoRequest { private String lat; private String lng; - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - - public String getSuite() { - return suite; - } - - public void setSuite(String suite) { - this.suite = suite; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getZipcode() { - return zipcode; - } - - public void setZipcode(String zipcode) { - this.zipcode = zipcode; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - public String getLng() { - return lng; - } - - public void setLng(String lng) { - this.lng = lng; - } - - public String getCompanyName() { - return companyName; - } - - public void setCompanyName(String companyName) { - this.companyName = companyName; - } - - public String getCatchPhrase() { - return catchPhrase; - } - - public void setCatchPhrase(String catchPhrase) { - this.catchPhrase = catchPhrase; - } - - public String getBs() { - return bs; - } - - public void setBs(String bs) { - this.bs = bs; - } - - public String getWebsite() { - return website; - } - - public void setWebsite(String website) { - this.website = website; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/JwtAuthenticationResponse.java b/src/main/java/com/sopromadze/blogapi/payload/JwtAuthenticationResponse.java index 47f2d1bb..148aa475 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/JwtAuthenticationResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/JwtAuthenticationResponse.java @@ -1,26 +1,14 @@ package com.sopromadze.blogapi.payload; -public class JwtAuthenticationResponse { - private String accessToken; - private String tokenType = "Bearer"; - - public JwtAuthenticationResponse(String accessToken) { - this.accessToken = accessToken; - } +import lombok.Data; - public String getAccessToken() { - return accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } +@Data +public class JwtAuthenticationResponse { + private String accessToken; + private String tokenType = "Bearer"; - public String getTokenType() { - return tokenType; - } + public JwtAuthenticationResponse(String accessToken) { + this.accessToken = accessToken; + } - public void setTokenType(String tokenType) { - this.tokenType = tokenType; - } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/LoginRequest.java b/src/main/java/com/sopromadze/blogapi/payload/LoginRequest.java index 4a04b5cb..ac1b0ee8 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/LoginRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/LoginRequest.java @@ -1,27 +1,14 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import javax.validation.constraints.NotBlank; +@Data public class LoginRequest { - @NotBlank - private String usernameOrEmail; - - @NotBlank - private String password; - - public String getUsernameOrEmail() { - return usernameOrEmail; - } - - public void setUsernameOrEmail(String usernameOrEmail) { - this.usernameOrEmail = usernameOrEmail; - } - - public String getPassword() { - return password; - } + @NotBlank + private String usernameOrEmail; - public void setPassword(String password) { - this.password = password; - } + @NotBlank + private String password; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/PagedResponse.java b/src/main/java/com/sopromadze/blogapi/payload/PagedResponse.java index d6d8bf3e..9e73e40e 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/PagedResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/PagedResponse.java @@ -1,79 +1,48 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import java.util.ArrayList; import java.util.Collections; import java.util.List; +@Data public class PagedResponse { - private List content; - private int page; - private int size; - private long totalElements; - private int totalPages; - private boolean last; - - public PagedResponse(){ - - } - - public PagedResponse(List content, int page, int size, long totalElements, int totalPages, boolean last) { - setContent(content); - this.page = page; - this.size = size; - this.totalElements = totalElements; - this.totalPages = totalPages; - this.last = last; - } - - public List getContent() { + private List content; + private int page; + private int size; + private long totalElements; + private int totalPages; + private boolean last; + + public PagedResponse() { + + } + + public PagedResponse(List content, int page, int size, long totalElements, int totalPages, boolean last) { + setContent(content); + this.page = page; + this.size = size; + this.totalElements = totalElements; + this.totalPages = totalPages; + this.last = last; + } + + public List getContent() { return content == null ? null : new ArrayList<>(content); - } + } - public final void setContent(List content) { + public final void setContent(List content) { if (content == null) { this.content = null; } else { this.content = Collections.unmodifiableList(content); } - } - - public int getPage() { - return page; - } - - public void setPage(int page) { - this.page = page; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - this.size = size; - } - - public long getTotalElements() { - return totalElements; - } - - public void setTotalElements(long totalElements) { - this.totalElements = totalElements; - } - - public int getTotalPages() { - return totalPages; - } + } - public void setTotalPages(int totalPages) { - this.totalPages = totalPages; - } - public boolean isLast() { - return last; - } - public void setLast(boolean last) { - this.last = last; - } + public boolean isLast() { + return last; + } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/PhotoRequest.java b/src/main/java/com/sopromadze/blogapi/payload/PhotoRequest.java index 6a7ac57d..74950489 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/PhotoRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/PhotoRequest.java @@ -1,55 +1,26 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +@Data public class PhotoRequest { - @NotBlank - @Size(min = 3) - private String title; - - @NotBlank - @Size(min = 10) - private String url; - - @NotBlank - @Size(min = 10) - private String thumbnailUrl; - - @NotNull - private Long albumId; - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getThumbnailUrl() { - return thumbnailUrl; - } + @NotBlank + @Size(min = 3) + private String title; - public void setThumbnailUrl(String thumbnailUrl) { - this.thumbnailUrl = thumbnailUrl; - } + @NotBlank + @Size(min = 10) + private String url; - public Long getAlbumId() { - return albumId; - } + @NotBlank + @Size(min = 10) + private String thumbnailUrl; - public void setAlbumId(Long albumId) { - this.albumId = albumId; - } + @NotNull + private Long albumId; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/PhotoResponse.java b/src/main/java/com/sopromadze/blogapi/payload/PhotoResponse.java index 2038142f..e695b977 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/PhotoResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/PhotoResponse.java @@ -1,57 +1,21 @@ package com.sopromadze.blogapi.payload; -public class PhotoResponse { - private Long id; - private String title; - private String url; - private String thumbnailUrl; - private Long albumId; - - public PhotoResponse(Long id, String title, String url, String thumbnailUrl, Long albumId) { - this.id = id; - this.title = title; - this.url = url; - this.thumbnailUrl = thumbnailUrl; - this.albumId = albumId; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } +import lombok.Data; - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getThumbnailUrl() { - return thumbnailUrl; - } - - public void setThumbnailUrl(String thumbnailUrl) { - this.thumbnailUrl = thumbnailUrl; - } - - public Long getAlbumId() { - return albumId; - } +@Data +public class PhotoResponse { + private Long id; + private String title; + private String url; + private String thumbnailUrl; + private Long albumId; + + public PhotoResponse(Long id, String title, String url, String thumbnailUrl, Long albumId) { + this.id = id; + this.title = title; + this.url = url; + this.thumbnailUrl = thumbnailUrl; + this.albumId = albumId; + } - public void setAlbumId(Long albumId) { - this.albumId = albumId; - } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/PostRequest.java b/src/main/java/com/sopromadze/blogapi/payload/PostRequest.java index 562e36f6..28d7ed13 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/PostRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/PostRequest.java @@ -1,13 +1,15 @@ package com.sopromadze.blogapi.payload; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +@Data public class PostRequest { @NotBlank @@ -23,37 +25,13 @@ public class PostRequest { private List tags; - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - public Long getCategoryId() { - return categoryId; - } - - public void setCategoryId(Long categoryId) { - this.categoryId = categoryId; - } - public List getTags() { - + return tags == null ? Collections.emptyList() : new ArrayList<>(tags); } public void setTags(List tags) { - + if (tags == null) { this.tags = null; } else { diff --git a/src/main/java/com/sopromadze/blogapi/payload/PostResponse.java b/src/main/java/com/sopromadze/blogapi/payload/PostResponse.java index 0416755f..f054e518 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/PostResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/PostResponse.java @@ -1,39 +1,27 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import java.util.ArrayList; import java.util.Collections; import java.util.List; +@Data public class PostResponse { - private String title; - private String body; - private String category; - private List tags; - - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } - public String getBody() { - return body; - } - public void setBody(String body) { - this.body = body; - } - public String getCategory() { - return category; - } - public void setCategory(String category) { - this.category = category; - } + private String title; + private String body; + private String category; + private List tags; + + + public List getTags() { - + return tags == null ? null : new ArrayList<>(tags); } + public void setTags(List tags) { - + if (tags == null) { this.tags = null; } else { diff --git a/src/main/java/com/sopromadze/blogapi/payload/SignUpRequest.java b/src/main/java/com/sopromadze/blogapi/payload/SignUpRequest.java index 46eeb955..3f993f13 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/SignUpRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/SignUpRequest.java @@ -1,68 +1,31 @@ package com.sopromadze.blogapi.payload; +import lombok.Data; + import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; +@Data public class SignUpRequest { - @NotBlank - @Size(min = 4, max = 40) - private String firstName; - - @NotBlank - @Size(min = 4, max = 40) - private String lastName; - - @NotBlank - @Size(min = 3, max = 15) - private String username; - - @NotBlank - @Size(max = 40) - @Email - private String email; - - @NotBlank - @Size(min = 6, max = 20) - private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } + @NotBlank + @Size(min = 4, max = 40) + private String firstName; + + @NotBlank + @Size(min = 4, max = 40) + private String lastName; + + @NotBlank + @Size(min = 3, max = 15) + private String username; + + @NotBlank + @Size(max = 40) + @Email + private String email; + + @NotBlank + @Size(min = 6, max = 20) + private String password; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java b/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java index 6952da87..b112bea5 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java +++ b/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java @@ -1,24 +1,11 @@ package com.sopromadze.blogapi.payload; -public abstract class UserDateAuditPayload extends DateAuditPayload { - private Long createdBy; - - private Long updatedBy; - - public Long getCreatedBy() { - return createdBy; - } +import lombok.Data; - public void setCreatedBy(Long createdBy) { - this.createdBy = createdBy; - } - - public Long getUpdatedBy() { - return updatedBy; - } +@Data +public abstract class UserDateAuditPayload extends DateAuditPayload { + private Long createdBy; - public void setUpdatedBy(Long updatedBy) { - this.updatedBy = updatedBy; - } + private Long updatedBy; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/UserIdentityAvailability.java b/src/main/java/com/sopromadze/blogapi/payload/UserIdentityAvailability.java index d2dffb93..c5d09fc2 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/UserIdentityAvailability.java +++ b/src/main/java/com/sopromadze/blogapi/payload/UserIdentityAvailability.java @@ -1,17 +1,11 @@ package com.sopromadze.blogapi.payload; -public class UserIdentityAvailability { - private Boolean available; - - public UserIdentityAvailability(Boolean available) { - this.available = available; - } +import lombok.AllArgsConstructor; +import lombok.Data; - public Boolean getAvailable() { - return available; - } +@Data +@AllArgsConstructor +public class UserIdentityAvailability { + private Boolean available; - public void setAvailable(Boolean available) { - this.available = available; - } } diff --git a/src/main/java/com/sopromadze/blogapi/payload/UserProfile.java b/src/main/java/com/sopromadze/blogapi/payload/UserProfile.java index 968ede71..b428ea12 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/UserProfile.java +++ b/src/main/java/com/sopromadze/blogapi/payload/UserProfile.java @@ -2,125 +2,25 @@ import com.sopromadze.blogapi.model.user.Address; import com.sopromadze.blogapi.model.user.Company; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import java.time.Instant; +@Data +@AllArgsConstructor +@NoArgsConstructor public class UserProfile { - private Long id; - private String username; - private String firstName; - private String lastName; - private Instant joinedAt; - private String email; - private Address address; - private String phone; - private String website; - private Company company; - private Long postCount; - - public UserProfile(){ - - } - - public UserProfile(Long id, String username, String firstName, String lastName, Instant joinedAt, String email, Address address, String phone, String website, Company company, Long postCount) { - this.id = id; - this.username = username; - this.firstName = firstName; - this.lastName = lastName; - this.joinedAt = joinedAt; - this.email = email; - this.address = address; - this.phone = phone; - this.website = website; - this.company = company; - this.postCount = postCount; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public Instant getJoinedAt() { - return joinedAt; - } - - public void setJoinedAt(Instant joinedAt) { - this.joinedAt = joinedAt; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Address getAddress() { - return address; - } - - public void setAddress(Address address) { - this.address = address; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public String getWebsite() { - return website; - } - - public void setWebsite(String website) { - this.website = website; - } - - public Company getCompany() { - return company; - } - - public void setCompany(Company company) { - this.company = company; - } - - public Long getPostCount() { - return postCount; - } - - public void setPostCount(Long postCount) { - this.postCount = postCount; - } + private Long id; + private String username; + private String firstName; + private String lastName; + private Instant joinedAt; + private String email; + private Address address; + private String phone; + private String website; + private Company company; + private Long postCount; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/UserSummary.java b/src/main/java/com/sopromadze/blogapi/payload/UserSummary.java index f1a1c3c3..7fe8fe92 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/UserSummary.java +++ b/src/main/java/com/sopromadze/blogapi/payload/UserSummary.java @@ -1,47 +1,13 @@ package com.sopromadze.blogapi.payload; -public class UserSummary { - private Long id; - private String username; - private String firstName; - private String lastName; - - public UserSummary(Long id, String username, String firstName, String lastName) { - this.id = id; - this.username = username; - this.firstName = firstName; - this.lastName = lastName; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getUsername() { - return username; - } +import lombok.AllArgsConstructor; +import lombok.Data; - public void setUsername(String username) { - this.username = username; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } +@Data +@AllArgsConstructor +public class UserSummary { + private Long id; + private String username; + private String firstName; + private String lastName; } diff --git a/src/main/java/com/sopromadze/blogapi/payload/request/AlbumRequest.java b/src/main/java/com/sopromadze/blogapi/payload/request/AlbumRequest.java index b1a48284..83e4f1eb 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/request/AlbumRequest.java +++ b/src/main/java/com/sopromadze/blogapi/payload/request/AlbumRequest.java @@ -1,13 +1,15 @@ package com.sopromadze.blogapi.payload.request; +import com.sopromadze.blogapi.model.Photo; +import com.sopromadze.blogapi.model.user.User; +import com.sopromadze.blogapi.payload.UserDateAuditPayload; +import lombok.Data; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.sopromadze.blogapi.model.photo.Photo; -import com.sopromadze.blogapi.model.user.User; -import com.sopromadze.blogapi.payload.UserDateAuditPayload; - +@Data public class AlbumRequest extends UserDateAuditPayload { private Long id; @@ -18,37 +20,13 @@ public class AlbumRequest extends UserDateAuditPayload { private List photo; - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - public List getPhoto() { - + return photo == null ? null : new ArrayList<>(photo); } public void setPhoto(List photo) { - + if (photo == null) { this.photo = null; } else { diff --git a/src/main/java/com/sopromadze/blogapi/repository/AlbumRepository.java b/src/main/java/com/sopromadze/blogapi/repository/AlbumRepository.java index 5630e218..12d6837f 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/AlbumRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/AlbumRepository.java @@ -1,13 +1,12 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.model.Album; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.album.Album; - @Repository public interface AlbumRepository extends JpaRepository { - Page findByCreatedBy(Long userId, Pageable pageable); + Page findByCreatedBy(Long userId, Pageable pageable); } diff --git a/src/main/java/com/sopromadze/blogapi/repository/CategoryRepository.java b/src/main/java/com/sopromadze/blogapi/repository/CategoryRepository.java index 179b206a..55c00914 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/CategoryRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/CategoryRepository.java @@ -1,10 +1,9 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.model.Category; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.category.Category; - @Repository public interface CategoryRepository extends JpaRepository { diff --git a/src/main/java/com/sopromadze/blogapi/repository/CommentRepository.java b/src/main/java/com/sopromadze/blogapi/repository/CommentRepository.java index 59b0b4e3..b4fb3be3 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/CommentRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/CommentRepository.java @@ -1,12 +1,11 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.model.Comment; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.comment.Comment; - @Repository public interface CommentRepository extends JpaRepository { Page findByPostId(Long postId, Pageable pageable); diff --git a/src/main/java/com/sopromadze/blogapi/repository/PhotoRepository.java b/src/main/java/com/sopromadze/blogapi/repository/PhotoRepository.java index 30c5bba5..a6f52698 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/PhotoRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/PhotoRepository.java @@ -1,12 +1,11 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.model.Photo; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.photo.Photo; - @Repository public interface PhotoRepository extends JpaRepository { Page findByAlbumId(Long albumId, Pageable pageable); diff --git a/src/main/java/com/sopromadze/blogapi/repository/PostRepository.java b/src/main/java/com/sopromadze/blogapi/repository/PostRepository.java index 9faf5591..a748afb8 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/PostRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/PostRepository.java @@ -1,19 +1,21 @@ package com.sopromadze.blogapi.repository; -import java.util.List; - +import com.sopromadze.blogapi.model.Post; +import com.sopromadze.blogapi.model.Tag; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.post.Post; -import com.sopromadze.blogapi.model.tag.Tag; +import java.util.List; @Repository public interface PostRepository extends JpaRepository { - Page findByCreatedBy(Long userId, Pageable pageable); - Page findByCategory(Long categoryId, Pageable pageable); - Page findByTags(List tags, Pageable pageable); - Long countByCreatedBy(Long userId); + Page findByCreatedBy(Long userId, Pageable pageable); + + Page findByCategory(Long categoryId, Pageable pageable); + + Page findByTags(List tags, Pageable pageable); + + Long countByCreatedBy(Long userId); } diff --git a/src/main/java/com/sopromadze/blogapi/repository/RoleRepository.java b/src/main/java/com/sopromadze/blogapi/repository/RoleRepository.java index 19a1e97f..067294c6 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/RoleRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/RoleRepository.java @@ -1,11 +1,10 @@ package com.sopromadze.blogapi.repository; -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; - import com.sopromadze.blogapi.model.role.Role; import com.sopromadze.blogapi.model.role.RoleName; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; public interface RoleRepository extends JpaRepository { Optional findByName(RoleName name); diff --git a/src/main/java/com/sopromadze/blogapi/repository/TagRepository.java b/src/main/java/com/sopromadze/blogapi/repository/TagRepository.java index 6f9352a1..e9620636 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/TagRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/TagRepository.java @@ -1,10 +1,9 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.model.Tag; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.tag.Tag; - @Repository public interface TagRepository extends JpaRepository { Tag findByName(String name); diff --git a/src/main/java/com/sopromadze/blogapi/repository/TodoRepository.java b/src/main/java/com/sopromadze/blogapi/repository/TodoRepository.java index 67f5512f..3cb55e71 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/TodoRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/TodoRepository.java @@ -1,12 +1,11 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.model.Todo; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.todo.Todo; - @Repository public interface TodoRepository extends JpaRepository { Page findByCreatedBy(Long userId, Pageable pageable); diff --git a/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java b/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java index 92629c30..ef88331a 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java @@ -1,13 +1,11 @@ package com.sopromadze.blogapi.repository; -import java.util.Optional; - -import javax.validation.constraints.NotBlank; - +import com.sopromadze.blogapi.model.user.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.sopromadze.blogapi.model.user.User; +import javax.validation.constraints.NotBlank; +import java.util.Optional; @Repository public interface UserRepository extends JpaRepository { diff --git a/src/main/java/com/sopromadze/blogapi/security/CurrentUser.java b/src/main/java/com/sopromadze/blogapi/security/CurrentUser.java index 2833d6a4..400b4a48 100644 --- a/src/main/java/com/sopromadze/blogapi/security/CurrentUser.java +++ b/src/main/java/com/sopromadze/blogapi/security/CurrentUser.java @@ -2,9 +2,13 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; -@Target({ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) +@Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @AuthenticationPrincipal diff --git a/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationEntryPoint.java b/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationEntryPoint.java index bc0913eb..b9f644ab 100644 --- a/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationEntryPoint.java +++ b/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationEntryPoint.java @@ -13,10 +13,12 @@ @Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { - private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class); - @Override - public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { - LOGGER.error("Responding with unauthorized error. Message - {}", e.getMessage()); - httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Sorry, You're not authorized to access this resource."); - } + private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class); + + @Override + public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) + throws IOException, ServletException { + LOGGER.error("Responding with unauthorized error. Message - {}", e.getMessage()); + httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Sorry, You're not authorized to access this resource."); + } } diff --git a/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationFilter.java b/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationFilter.java index 18af240d..3c162554 100644 --- a/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationFilter.java +++ b/src/main/java/com/sopromadze/blogapi/security/JwtAuthenticationFilter.java @@ -1,5 +1,6 @@ package com.sopromadze.blogapi.security; +import com.sopromadze.blogapi.service.CustomUserDetailsService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -10,8 +11,6 @@ import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; -import com.sopromadze.blogapi.service.CustomUserDetailsService; - import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -19,40 +18,40 @@ import java.io.IOException; public class JwtAuthenticationFilter extends OncePerRequestFilter { - @Autowired - private JwtTokenProvider tokenProvider; - - @Autowired - private CustomUserDetailsService customUserDetailsService; - - private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationFilter.class); - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - try{ - String jwt = getJwtFromRequest(request); - - if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)){ - Long userId = tokenProvider.getUserIdFromJWT(jwt); - - UserDetails userDetails = customUserDetailsService.loadUserById(userId); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - - SecurityContextHolder.getContext().setAuthentication(authenticationToken); - } - } catch (Exception ex){ - LOGGER.error("Could not set user authentication in security context", ex); - } - - filterChain.doFilter(request, response); - } - - private String getJwtFromRequest(HttpServletRequest request){ - String bearerToken = request.getHeader("Authorization"); - if(StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")){ - return bearerToken.substring(7, bearerToken.length()); - } - return null; - } + private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationFilter.class); + @Autowired + private JwtTokenProvider tokenProvider; + @Autowired + private CustomUserDetailsService customUserDetailsService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + try { + String jwt = getJwtFromRequest(request); + + if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) { + Long userId = tokenProvider.getUserIdFromJWT(jwt); + + UserDetails userDetails = customUserDetailsService.loadUserById(userId); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, + userDetails.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + } catch (Exception ex) { + LOGGER.error("Could not set user authentication in security context", ex); + } + + filterChain.doFilter(request, response); + } + + private String getJwtFromRequest(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { + return bearerToken.substring(7, bearerToken.length()); + } + return null; + } } diff --git a/src/main/java/com/sopromadze/blogapi/security/JwtTokenProvider.java b/src/main/java/com/sopromadze/blogapi/security/JwtTokenProvider.java index cb5ad334..77fad327 100644 --- a/src/main/java/com/sopromadze/blogapi/security/JwtTokenProvider.java +++ b/src/main/java/com/sopromadze/blogapi/security/JwtTokenProvider.java @@ -1,13 +1,5 @@ package com.sopromadze.blogapi.security; -import java.util.Date; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Component; - import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwts; @@ -15,55 +7,62 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.UnsupportedJwtException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import java.util.Date; @Component public class JwtTokenProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenProvider.class); + private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenProvider.class); - @Value(value = "${app.jwtSecret}") - private String jwtSecret; + @Value(value = "${app.jwtSecret}") + private String jwtSecret; - @Value(value = "${app.jwtExpirationInMs}") - private int jwtExpirationInMs; + @Value(value = "${app.jwtExpirationInMs}") + private int jwtExpirationInMs; - public String generateToken(Authentication authentication){ - UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(); + public String generateToken(Authentication authentication) { + UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(); - Date now = new Date(); - Date expiryDate = new Date(now.getTime() + jwtExpirationInMs); + Date now = new Date(); + Date expiryDate = new Date(now.getTime() + jwtExpirationInMs); - return Jwts.builder() - .setSubject(Long.toString(userPrincipal.getId())) - .setIssuedAt(new Date()) - .setExpiration(expiryDate) - .signWith(SignatureAlgorithm.HS512, jwtSecret) - .compact(); - } + return Jwts.builder() + .setSubject(Long.toString(userPrincipal.getId())) + .setIssuedAt(new Date()) + .setExpiration(expiryDate) + .signWith(SignatureAlgorithm.HS512, jwtSecret) + .compact(); + } - public Long getUserIdFromJWT(String token){ - Claims claims = Jwts.parser() - .setSigningKey(jwtSecret) - .parseClaimsJws(token) - .getBody(); + public Long getUserIdFromJWT(String token) { + Claims claims = Jwts.parser() + .setSigningKey(jwtSecret) + .parseClaimsJws(token) + .getBody(); - return Long.valueOf(claims.getSubject()); - } + return Long.valueOf(claims.getSubject()); + } - public boolean validateToken(String authToken){ - try { - Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken); - return true; - } catch (SignatureException ex){ - LOGGER.error("Invalid JWT signature"); - } catch (MalformedJwtException ex){ - LOGGER.error("Invalid JWT token"); - } catch (ExpiredJwtException ex){ - LOGGER.error("Expired JWT token"); - } catch (UnsupportedJwtException ex){ - LOGGER.error("Unsupported JWT token"); - } catch (IllegalArgumentException ex){ - LOGGER.error("JWT claims string is empty"); - } - return false; - } + public boolean validateToken(String authToken) { + try { + Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken); + return true; + } catch (SignatureException ex) { + LOGGER.error("Invalid JWT signature"); + } catch (MalformedJwtException ex) { + LOGGER.error("Invalid JWT token"); + } catch (ExpiredJwtException ex) { + LOGGER.error("Expired JWT token"); + } catch (UnsupportedJwtException ex) { + LOGGER.error("Unsupported JWT token"); + } catch (IllegalArgumentException ex) { + LOGGER.error("JWT claims string is empty"); + } + return false; + } } diff --git a/src/main/java/com/sopromadze/blogapi/security/UserPrincipal.java b/src/main/java/com/sopromadze/blogapi/security/UserPrincipal.java index 18751533..3402459f 100644 --- a/src/main/java/com/sopromadze/blogapi/security/UserPrincipal.java +++ b/src/main/java/com/sopromadze/blogapi/security/UserPrincipal.java @@ -1,18 +1,17 @@ package com.sopromadze.blogapi.security; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.sopromadze.blogapi.model.user.User; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.user.User; - public class UserPrincipal implements UserDetails { private static final long serialVersionUID = 1L; @@ -40,7 +39,7 @@ public UserPrincipal(Long id, String firstName, String lastName, String username this.username = username; this.email = email; this.password = password; - + if (authorities == null) { this.authorities = null; } else { diff --git a/src/main/java/com/sopromadze/blogapi/service/AlbumService.java b/src/main/java/com/sopromadze/blogapi/service/AlbumService.java index a98092ff..ef4a3621 100644 --- a/src/main/java/com/sopromadze/blogapi/service/AlbumService.java +++ b/src/main/java/com/sopromadze/blogapi/service/AlbumService.java @@ -1,13 +1,12 @@ package com.sopromadze.blogapi.service; -import org.springframework.http.ResponseEntity; - -import com.sopromadze.blogapi.model.album.Album; +import com.sopromadze.blogapi.model.Album; import com.sopromadze.blogapi.payload.AlbumResponse; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.payload.request.AlbumRequest; import com.sopromadze.blogapi.security.UserPrincipal; +import org.springframework.http.ResponseEntity; public interface AlbumService { @@ -23,4 +22,4 @@ public interface AlbumService { PagedResponse getUserAlbums(String username, int page, int size); -} \ No newline at end of file +} diff --git a/src/main/java/com/sopromadze/blogapi/service/CategoryService.java b/src/main/java/com/sopromadze/blogapi/service/CategoryService.java index ce6369b2..65734a3e 100644 --- a/src/main/java/com/sopromadze/blogapi/service/CategoryService.java +++ b/src/main/java/com/sopromadze/blogapi/service/CategoryService.java @@ -1,12 +1,11 @@ package com.sopromadze.blogapi.service; -import org.springframework.http.ResponseEntity; - import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.category.Category; +import com.sopromadze.blogapi.model.Category; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.security.UserPrincipal; +import org.springframework.http.ResponseEntity; public interface CategoryService { @@ -21,4 +20,4 @@ ResponseEntity updateCategory(Long id, Category newCategory, UserPrinc ResponseEntity deleteCategory(Long id, UserPrincipal currentUser) throws UnauthorizedException; -} \ No newline at end of file +} diff --git a/src/main/java/com/sopromadze/blogapi/service/CommentService.java b/src/main/java/com/sopromadze/blogapi/service/CommentService.java index 65ef8d88..cdbc34de 100644 --- a/src/main/java/com/sopromadze/blogapi/service/CommentService.java +++ b/src/main/java/com/sopromadze/blogapi/service/CommentService.java @@ -1,6 +1,6 @@ package com.sopromadze.blogapi.service; -import com.sopromadze.blogapi.model.comment.Comment; +import com.sopromadze.blogapi.model.Comment; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.CommentRequest; import com.sopromadze.blogapi.payload.PagedResponse; @@ -18,4 +18,4 @@ public interface CommentService { ApiResponse deleteComment(Long postId, Long id, UserPrincipal currentUser); -} \ No newline at end of file +} diff --git a/src/main/java/com/sopromadze/blogapi/service/PostService.java b/src/main/java/com/sopromadze/blogapi/service/PostService.java index 23e2f6cd..d4754205 100644 --- a/src/main/java/com/sopromadze/blogapi/service/PostService.java +++ b/src/main/java/com/sopromadze/blogapi/service/PostService.java @@ -1,6 +1,6 @@ package com.sopromadze.blogapi.service; -import com.sopromadze.blogapi.model.post.Post; +import com.sopromadze.blogapi.model.Post; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.payload.PostRequest; @@ -25,4 +25,4 @@ public interface PostService { Post getPost(Long id); -} \ No newline at end of file +} diff --git a/src/main/java/com/sopromadze/blogapi/service/TagService.java b/src/main/java/com/sopromadze/blogapi/service/TagService.java index 134a63ff..db321cca 100644 --- a/src/main/java/com/sopromadze/blogapi/service/TagService.java +++ b/src/main/java/com/sopromadze/blogapi/service/TagService.java @@ -1,6 +1,6 @@ package com.sopromadze.blogapi.service; -import com.sopromadze.blogapi.model.tag.Tag; +import com.sopromadze.blogapi.model.Tag; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.security.UserPrincipal; @@ -17,4 +17,4 @@ public interface TagService { ApiResponse deleteTag(Long id, UserPrincipal currentUser); -} \ No newline at end of file +} diff --git a/src/main/java/com/sopromadze/blogapi/service/TodoService.java b/src/main/java/com/sopromadze/blogapi/service/TodoService.java index a54866ae..23e7903d 100644 --- a/src/main/java/com/sopromadze/blogapi/service/TodoService.java +++ b/src/main/java/com/sopromadze/blogapi/service/TodoService.java @@ -1,6 +1,6 @@ package com.sopromadze.blogapi.service; -import com.sopromadze.blogapi.model.todo.Todo; +import com.sopromadze.blogapi.model.Todo; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.security.UserPrincipal; @@ -21,4 +21,4 @@ public interface TodoService { ApiResponse deleteTodo(Long id, UserPrincipal currentUser); -} \ No newline at end of file +} diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java index 31fb00d9..008196eb 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java @@ -1,25 +1,8 @@ package com.sopromadze.blogapi.service.impl; -import static com.sopromadze.blogapi.utils.AppConstants.ID; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.BlogapiException; import com.sopromadze.blogapi.exception.ResourceNotFoundException; -import com.sopromadze.blogapi.model.album.Album; +import com.sopromadze.blogapi.model.Album; import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.model.user.User; import com.sopromadze.blogapi.payload.AlbumResponse; @@ -31,13 +14,27 @@ import com.sopromadze.blogapi.security.UserPrincipal; import com.sopromadze.blogapi.service.AlbumService; import com.sopromadze.blogapi.utils.AppUtils; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.sopromadze.blogapi.utils.AppConstants.ID; @Service public class AlbumServiceImpl implements AlbumService { private static final String CREATED_AT = "createdAt"; - - private static final String ALBUM_STR = "Album"; private static final String USER_STR = "User"; @@ -47,90 +44,96 @@ public class AlbumServiceImpl implements AlbumService { private static final String YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION = "You don't have permission to make this operation"; @Autowired - private AlbumRepository albumRepository; - + private AlbumRepository albumRepository; + @Autowired - private UserRepository userRepository; - + private UserRepository userRepository; + @Autowired private ModelMapper modelMapper; - - - @Override - public PagedResponse getAllAlbums(int page, int size){ - AppUtils.validatePageNumberAndSize(page, size); - - Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); - - Page albums = albumRepository.findAll(pageable); - - if (albums.getNumberOfElements() == 0){ - return new PagedResponse<>(Collections.emptyList(), albums.getNumber(), albums.getSize(), albums.getTotalElements(), albums.getTotalPages(), albums.isLast()); - } - - List albumResponses = Arrays.asList(modelMapper.map(albums.getContent(), AlbumResponse[].class)); - - return new PagedResponse<>(albumResponses, albums.getNumber(), albums.getSize(), albums.getTotalElements(), albums.getTotalPages(), albums.isLast()); - } - - @Override - public ResponseEntity addAlbum(AlbumRequest albumRequest, UserPrincipal currentUser){ - User user = userRepository.findByUsername(currentUser.getUsername()).orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); - - Album album = new Album(); - - modelMapper.map(albumRequest, album); - - album.setUser(user); - Album newAlbum = albumRepository.save(album); - return new ResponseEntity<>(newAlbum, HttpStatus.CREATED); - } - - @Override - public ResponseEntity getAlbum(Long id){ - Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); - return new ResponseEntity<>(album, HttpStatus.OK); - } - - @Override - public ResponseEntity updateAlbum(Long id, AlbumRequest newAlbum, UserPrincipal currentUser){ - Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); - User user = userRepository.findByUsername(currentUser.getUsername()).orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); - if (album.getUser().getId().equals(user.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))){ - album.setTitle(newAlbum.getTitle()); - Album updatedAlbum = albumRepository.save(album); - - AlbumResponse albumResponse = new AlbumResponse(); - - modelMapper.map(updatedAlbum, albumResponse); - - return new ResponseEntity<>(albumResponse, HttpStatus.OK); - } - - throw new BlogapiException(HttpStatus.UNAUTHORIZED, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - } - - @Override - public ResponseEntity deleteAlbum(Long id, UserPrincipal currentUser){ - Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); - User user = userRepository.findByUsername(currentUser.getUsername()).orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); - if (album.getUser().getId().equals(user.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))){ - albumRepository.deleteById(id); - return new ResponseEntity<>(new ApiResponse(Boolean.TRUE, "You successfully deleted album"), HttpStatus.OK); - } - - throw new BlogapiException(HttpStatus.UNAUTHORIZED, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - } - - @Override - public PagedResponse getUserAlbums(String username, int page, int size){ - User user = userRepository.findByUsername(username).orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, username)); - Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); - - Page albums = albumRepository.findByCreatedBy(user.getId(), pageable); - - List content = albums.getNumberOfElements() > 0 ? albums.getContent() : Collections.emptyList(); - - return new PagedResponse<>(content, albums.getNumber(), albums.getSize(), albums.getTotalElements(), albums.getTotalPages(), albums.isLast()); - } + + @Override + public PagedResponse getAllAlbums(int page, int size) { + AppUtils.validatePageNumberAndSize(page, size); + + Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); + + Page albums = albumRepository.findAll(pageable); + + if (albums.getNumberOfElements() == 0) { + return new PagedResponse<>(Collections.emptyList(), albums.getNumber(), albums.getSize(), albums.getTotalElements(), + albums.getTotalPages(), albums.isLast()); + } + + List albumResponses = Arrays.asList(modelMapper.map(albums.getContent(), AlbumResponse[].class)); + + return new PagedResponse<>(albumResponses, albums.getNumber(), albums.getSize(), albums.getTotalElements(), albums.getTotalPages(), + albums.isLast()); + } + + @Override + public ResponseEntity addAlbum(AlbumRequest albumRequest, UserPrincipal currentUser) { + User user = userRepository.findByUsername(currentUser.getUsername()) + .orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); + + Album album = new Album(); + + modelMapper.map(albumRequest, album); + + album.setUser(user); + Album newAlbum = albumRepository.save(album); + return new ResponseEntity<>(newAlbum, HttpStatus.CREATED); + } + + @Override + public ResponseEntity getAlbum(Long id) { + Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); + return new ResponseEntity<>(album, HttpStatus.OK); + } + + @Override + public ResponseEntity updateAlbum(Long id, AlbumRequest newAlbum, UserPrincipal currentUser) { + Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); + User user = userRepository.findByUsername(currentUser.getUsername()) + .orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); + if (album.getUser().getId().equals(user.getId()) || currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + album.setTitle(newAlbum.getTitle()); + Album updatedAlbum = albumRepository.save(album); + + AlbumResponse albumResponse = new AlbumResponse(); + + modelMapper.map(updatedAlbum, albumResponse); + + return new ResponseEntity<>(albumResponse, HttpStatus.OK); + } + + throw new BlogapiException(HttpStatus.UNAUTHORIZED, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); + } + + @Override + public ResponseEntity deleteAlbum(Long id, UserPrincipal currentUser) { + Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); + User user = userRepository.findByUsername(currentUser.getUsername()) + .orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); + if (album.getUser().getId().equals(user.getId()) || currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + albumRepository.deleteById(id); + return new ResponseEntity<>(new ApiResponse(Boolean.TRUE, "You successfully deleted album"), HttpStatus.OK); + } + + throw new BlogapiException(HttpStatus.UNAUTHORIZED, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); + } + + @Override + public PagedResponse getUserAlbums(String username, int page, int size) { + User user = userRepository.findByUsername(username).orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, username)); + Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); + + Page albums = albumRepository.findByCreatedBy(user.getId(), pageable); + + List content = albums.getNumberOfElements() > 0 ? albums.getContent() : Collections.emptyList(); + + return new PagedResponse<>(content, albums.getNumber(), albums.getSize(), albums.getTotalElements(), albums.getTotalPages(), albums.isLast()); + } } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java index 54b40f1b..cbe392dc 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java @@ -1,8 +1,15 @@ package com.sopromadze.blogapi.service.impl; -import java.util.Collections; -import java.util.List; - +import com.sopromadze.blogapi.exception.ResourceNotFoundException; +import com.sopromadze.blogapi.exception.UnauthorizedException; +import com.sopromadze.blogapi.model.Category; +import com.sopromadze.blogapi.model.role.RoleName; +import com.sopromadze.blogapi.payload.ApiResponse; +import com.sopromadze.blogapi.payload.PagedResponse; +import com.sopromadze.blogapi.repository.CategoryRepository; +import com.sopromadze.blogapi.security.UserPrincipal; +import com.sopromadze.blogapi.service.CategoryService; +import com.sopromadze.blogapi.utils.AppUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -13,69 +20,64 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; -import com.sopromadze.blogapi.exception.ResourceNotFoundException; -import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.category.Category; -import com.sopromadze.blogapi.model.role.RoleName; -import com.sopromadze.blogapi.payload.ApiResponse; -import com.sopromadze.blogapi.payload.PagedResponse; -import com.sopromadze.blogapi.repository.CategoryRepository; -import com.sopromadze.blogapi.security.UserPrincipal; -import com.sopromadze.blogapi.service.CategoryService; -import com.sopromadze.blogapi.utils.AppUtils; +import java.util.Collections; +import java.util.List; @Service public class CategoryServiceImpl implements CategoryService { - + @Autowired private CategoryRepository categoryRepository; - + @Override - public PagedResponse getAllCategories(int page, int size){ + public PagedResponse getAllCategories(int page, int size) { AppUtils.validatePageNumberAndSize(page, size); - + Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "createdAt"); - + Page categories = categoryRepository.findAll(pageable); - + List content = categories.getNumberOfElements() == 0 ? Collections.emptyList() : categories.getContent(); - - return new PagedResponse(content, categories.getNumber(), categories.getSize(), categories.getTotalElements(), categories.getTotalPages(), categories.isLast()); + + return new PagedResponse<>(content, categories.getNumber(), categories.getSize(), categories.getTotalElements(), + categories.getTotalPages(), categories.isLast()); } - + @Override - public ResponseEntity getCategory(Long id){ - Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Category", "id", id)); - return new ResponseEntity<>(category, HttpStatus.OK); - } - + public ResponseEntity getCategory(Long id) { + Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Category", "id", id)); + return new ResponseEntity<>(category, HttpStatus.OK); + } + @Override - public ResponseEntity addCategory(Category category, UserPrincipal currentUser){ - Category newCategory = categoryRepository.save(category); - return new ResponseEntity<>(newCategory, HttpStatus.CREATED); - } - + public ResponseEntity addCategory(Category category, UserPrincipal currentUser) { + Category newCategory = categoryRepository.save(category); + return new ResponseEntity<>(newCategory, HttpStatus.CREATED); + } + @Override public ResponseEntity updateCategory(Long id, Category newCategory, UserPrincipal currentUser) throws UnauthorizedException { - Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Category", "id", id)); - if (category.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))){ - category.setName(newCategory.getName()); - Category updatedCategory = categoryRepository.save(category); - return new ResponseEntity<>(updatedCategory, HttpStatus.OK); - } - - throw new UnauthorizedException("You don't have permission to edit this category"); - } - + Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Category", "id", id)); + if (category.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + category.setName(newCategory.getName()); + Category updatedCategory = categoryRepository.save(category); + return new ResponseEntity<>(updatedCategory, HttpStatus.OK); + } + + throw new UnauthorizedException("You don't have permission to edit this category"); + } + @Override - public ResponseEntity deleteCategory(Long id, UserPrincipal currentUser) throws UnauthorizedException{ - Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("category", "id", id)); - if (category.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))){ - categoryRepository.deleteById(id); - return new ResponseEntity<>(new ApiResponse(Boolean.TRUE, "You successfully deleted category"), HttpStatus.OK); - } - throw new UnauthorizedException("You don't have permission to delete this category"); - } + public ResponseEntity deleteCategory(Long id, UserPrincipal currentUser) throws UnauthorizedException { + Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("category", "id", id)); + if (category.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + categoryRepository.deleteById(id); + return new ResponseEntity<>(new ApiResponse(Boolean.TRUE, "You successfully deleted category"), HttpStatus.OK); + } + throw new UnauthorizedException("You don't have permission to delete this category"); + } } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java index 69805cb5..f09df86d 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java @@ -1,18 +1,9 @@ package com.sopromadze.blogapi.service.impl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.BlogapiException; import com.sopromadze.blogapi.exception.ResourceNotFoundException; -import com.sopromadze.blogapi.model.comment.Comment; -import com.sopromadze.blogapi.model.post.Post; +import com.sopromadze.blogapi.model.Comment; +import com.sopromadze.blogapi.model.Post; import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.model.user.User; import com.sopromadze.blogapi.payload.ApiResponse; @@ -24,6 +15,14 @@ import com.sopromadze.blogapi.security.UserPrincipal; import com.sopromadze.blogapi.service.CommentService; import com.sopromadze.blogapi.utils.AppUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; @Service public class CommentServiceImpl implements CommentService { @@ -55,7 +54,7 @@ public PagedResponse getAllComments(Long postId, int page, int size) { Page comments = commentRepository.findByPostId(postId, pageable); - return new PagedResponse(comments.getContent(), comments.getNumber(), comments.getSize(), + return new PagedResponse<>(comments.getContent(), comments.getNumber(), comments.getSize(), comments.getTotalElements(), comments.getTotalPages(), comments.isLast()); } @@ -70,9 +69,7 @@ public Comment addComment(CommentRequest commentRequest, Long postId, UserPrinci comment.setPost(post); comment.setName(currentUser.getUsername()); comment.setEmail(currentUser.getEmail()); - Comment newComment = commentRepository.save(comment); - - return newComment; + return commentRepository.save(comment); } @Override @@ -84,7 +81,7 @@ public Comment getComment(Long postId, Long id) { if (comment.getPost().getId().equals(post.getId())) { return comment; } - + throw new BlogapiException(HttpStatus.BAD_REQUEST, COMMENT_DOES_NOT_BELONG_TO_POST); } @@ -103,10 +100,9 @@ public Comment updateComment(Long postId, Long id, CommentRequest commentRequest if (comment.getUser().getId().equals(currentUser.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { comment.setBody(commentRequest.getBody()); - Comment updatedComment = commentRepository.save(comment); - return updatedComment; + return commentRepository.save(comment); } - + throw new BlogapiException(HttpStatus.UNAUTHORIZED, YOU_DON_T_HAVE_PERMISSION_TO + "update" + THIS_COMMENT); } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java index 71071666..5014497e 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java @@ -4,7 +4,6 @@ import com.sopromadze.blogapi.repository.UserRepository; import com.sopromadze.blogapi.security.UserPrincipal; import com.sopromadze.blogapi.service.CustomUserDetailsService; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -14,22 +13,23 @@ import javax.transaction.Transactional; @Service -public class CustomUserDetailsServiceImpl implements UserDetailsService, CustomUserDetailsService { +public class CustomUserDetailsServiceImpl implements UserDetailsService, CustomUserDetailsService { @Autowired private UserRepository userRepository; - @Override - @Transactional - public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException { - User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail).orElseThrow(() -> new UsernameNotFoundException(String.format("User not found with this username or email: %s", usernameOrEmail))); - return UserPrincipal.create(user); - } + @Override + @Transactional + public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException { + User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail) + .orElseThrow(() -> new UsernameNotFoundException(String.format("User not found with this username or email: %s", usernameOrEmail))); + return UserPrincipal.create(user); + } - @Override + @Override @Transactional - public UserDetails loadUserById(Long id){ - User user = userRepository.findById(id).orElseThrow(() -> new UsernameNotFoundException(String.format("User not found with id: %s", id))); + public UserDetails loadUserById(Long id) { + User user = userRepository.findById(id).orElseThrow(() -> new UsernameNotFoundException(String.format("User not found with id: %s", id))); - return UserPrincipal.create(user); - } + return UserPrincipal.create(user); + } } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/PhotoServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/PhotoServiceImpl.java index b43c29fd..dfa90b86 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/PhotoServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/PhotoServiceImpl.java @@ -1,26 +1,9 @@ package com.sopromadze.blogapi.service.impl; -import static com.sopromadze.blogapi.utils.AppConstants.ALBUM; -import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; -import static com.sopromadze.blogapi.utils.AppConstants.ID; -import static com.sopromadze.blogapi.utils.AppConstants.PHOTO; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.ResourceNotFoundException; import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.album.Album; -import com.sopromadze.blogapi.model.photo.Photo; +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.model.Photo; import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; @@ -32,6 +15,22 @@ import com.sopromadze.blogapi.service.PhotoService; import com.sopromadze.blogapi.utils.AppConstants; import com.sopromadze.blogapi.utils.AppUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static com.sopromadze.blogapi.utils.AppConstants.ALBUM; +import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; +import static com.sopromadze.blogapi.utils.AppConstants.ID; +import static com.sopromadze.blogapi.utils.AppConstants.PHOTO; @Service public class PhotoServiceImpl implements PhotoService { @@ -67,11 +66,9 @@ public PagedResponse getAllPhotos(int page, int size) { @Override public PhotoResponse getPhoto(Long id) { Photo photo = photoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(PHOTO, ID, id)); - - PhotoResponse photoResponse = new PhotoResponse(photo.getId(), photo.getTitle(), photo.getUrl(), + + return new PhotoResponse(photo.getId(), photo.getTitle(), photo.getUrl(), photo.getThumbnailUrl(), photo.getAlbum().getId()); - - return photoResponse; } @Override @@ -88,9 +85,9 @@ public PhotoResponse updatePhoto(Long id, PhotoRequest photoRequest, UserPrincip return new PhotoResponse(updatedPhoto.getId(), updatedPhoto.getTitle(), updatedPhoto.getUrl(), updatedPhoto.getThumbnailUrl(), updatedPhoto.getAlbum().getId()); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to update this photo"); - + throw new UnauthorizedException(apiResponse); } @@ -105,9 +102,9 @@ public PhotoResponse addPhoto(PhotoRequest photoRequest, UserPrincipal currentUs return new PhotoResponse(newPhoto.getId(), newPhoto.getTitle(), newPhoto.getUrl(), newPhoto.getThumbnailUrl(), newPhoto.getAlbum().getId()); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to add photo in this album"); - + throw new UnauthorizedException(apiResponse); } @@ -119,9 +116,9 @@ public ApiResponse deletePhoto(Long id, UserPrincipal currentUser) { photoRepository.deleteById(id); return new ApiResponse(Boolean.TRUE, "Photo deleted successfully"); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to delete this photo"); - + throw new UnauthorizedException(apiResponse); } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java index 5e94cffc..9ba5fa06 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java @@ -1,33 +1,12 @@ package com.sopromadze.blogapi.service.impl; -import static com.sopromadze.blogapi.utils.AppConstants.CATEGORY; -import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; -import static com.sopromadze.blogapi.utils.AppConstants.ID; -import static com.sopromadze.blogapi.utils.AppConstants.POST; -import static com.sopromadze.blogapi.utils.AppConstants.TAG; -import static com.sopromadze.blogapi.utils.AppConstants.USER; -import static com.sopromadze.blogapi.utils.AppConstants.USERNAME; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.BadRequestException; import com.sopromadze.blogapi.exception.ResourceNotFoundException; import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.category.Category; -import com.sopromadze.blogapi.model.post.Post; +import com.sopromadze.blogapi.model.Category; +import com.sopromadze.blogapi.model.Post; import com.sopromadze.blogapi.model.role.RoleName; -import com.sopromadze.blogapi.model.tag.Tag; +import com.sopromadze.blogapi.model.Tag; import com.sopromadze.blogapi.model.user.User; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; @@ -41,6 +20,26 @@ import com.sopromadze.blogapi.service.PostService; import com.sopromadze.blogapi.utils.AppConstants; import com.sopromadze.blogapi.utils.AppUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.sopromadze.blogapi.utils.AppConstants.CATEGORY; +import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; +import static com.sopromadze.blogapi.utils.AppConstants.ID; +import static com.sopromadze.blogapi.utils.AppConstants.POST; +import static com.sopromadze.blogapi.utils.AppConstants.TAG; +import static com.sopromadze.blogapi.utils.AppConstants.USER; +import static com.sopromadze.blogapi.utils.AppConstants.USERNAME; @Service public class PostServiceImpl implements PostService { @@ -125,8 +124,7 @@ public Post updatePost(Long id, PostRequest newPostRequest, UserPrincipal curren post.setTitle(newPostRequest.getTitle()); post.setBody(newPostRequest.getBody()); post.setCategory(category); - Post updatedPost = postRepository.save(post); - return updatedPost; + return postRepository.save(post); } ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to edit this post"); @@ -153,8 +151,8 @@ public PostResponse addPost(PostRequest postRequest, UserPrincipal currentUser) .orElseThrow(() -> new ResourceNotFoundException(USER, ID, 1L)); Category category = categoryRepository.findById(postRequest.getCategoryId()) .orElseThrow(() -> new ResourceNotFoundException(CATEGORY, ID, postRequest.getCategoryId())); - - List tags = new ArrayList(postRequest.getTags().size()); + + List tags = new ArrayList< >(postRequest.getTags().size()); for (String name : postRequest.getTags()) { Tag tag = tagRepository.findByName(name); @@ -178,7 +176,7 @@ public PostResponse addPost(PostRequest postRequest, UserPrincipal currentUser) postResponse.setBody(newPost.getBody()); postResponse.setCategory(newPost.getCategory().getName()); - List tagNames = new ArrayList(newPost.getTags().size()); + List tagNames = new ArrayList< >(newPost.getTags().size()); for (Tag tag : newPost.getTags()) { tagNames.add(tag.getName()); @@ -191,8 +189,7 @@ public PostResponse addPost(PostRequest postRequest, UserPrincipal currentUser) @Override public Post getPost(Long id) { - Post post = postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(POST, ID, id)); - return post; + return postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(POST, ID, id)); } private void validatePageNumberAndSize(int page, int size) { diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java index 359d3939..cb77efae 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java @@ -1,83 +1,81 @@ package com.sopromadze.blogapi.service.impl; -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.ResourceNotFoundException; import com.sopromadze.blogapi.exception.UnauthorizedException; import com.sopromadze.blogapi.model.role.RoleName; -import com.sopromadze.blogapi.model.tag.Tag; +import com.sopromadze.blogapi.model.Tag; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.repository.TagRepository; import com.sopromadze.blogapi.security.UserPrincipal; import com.sopromadze.blogapi.service.TagService; import com.sopromadze.blogapi.utils.AppUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; @Service public class TagServiceImpl implements TagService { - + @Autowired private TagRepository tagRepository; - + @Override - public PagedResponse getAllTags(int page, int size){ + public PagedResponse getAllTags(int page, int size) { AppUtils.validatePageNumberAndSize(page, size); - + Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "createdAt"); - + Page tags = tagRepository.findAll(pageable); - + List content = tags.getNumberOfElements() == 0 ? Collections.emptyList() : tags.getContent(); - - return new PagedResponse(content, tags.getNumber(), tags.getSize(), tags.getTotalElements(), tags.getTotalPages(), tags.isLast()); + + return new PagedResponse< >(content, tags.getNumber(), tags.getSize(), tags.getTotalElements(), tags.getTotalPages(), tags.isLast()); } - + @Override - public Tag getTag(Long id){ - Tag tag = tagRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Tag", "id", id)); - return tag; - } - + public Tag getTag(Long id) { + return tagRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Tag", "id", id)); + } + @Override - public Tag addTag(Tag tag, UserPrincipal currentUser){ - Tag newTag = tagRepository.save(tag); - return newTag; - } - + public Tag addTag(Tag tag, UserPrincipal currentUser) { + return tagRepository.save(tag); + } + @Override - public Tag updateTag(Long id, Tag newTag, UserPrincipal currentUser){ - Tag tag = tagRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Tag", "id", id)); - if (tag.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))){ - tag.setName(newTag.getName()); - Tag updatedTag = tagRepository.save(tag); - return updatedTag; - } - ApiResponse apiResponse =new ApiResponse(Boolean.FALSE, "You don't have permission to edit this tag"); - - throw new UnauthorizedException(apiResponse); - } - + public Tag updateTag(Long id, Tag newTag, UserPrincipal currentUser) { + Tag tag = tagRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Tag", "id", id)); + if (tag.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + tag.setName(newTag.getName()); + return tagRepository.save(tag); + } + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to edit this tag"); + + throw new UnauthorizedException(apiResponse); + } + @Override - public ApiResponse deleteTag(Long id, UserPrincipal currentUser){ - Tag tag = tagRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Tag", "id", id)); - if (tag.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))){ - tagRepository.deleteById(id); - return new ApiResponse(Boolean.TRUE, "You successfully deleted tag"); - } - - ApiResponse apiResponse =new ApiResponse(Boolean.FALSE, "You don't have permission to delete this tag"); - - throw new UnauthorizedException(apiResponse); - } + public ApiResponse deleteTag(Long id, UserPrincipal currentUser) { + Tag tag = tagRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Tag", "id", id)); + if (tag.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + tagRepository.deleteById(id); + return new ApiResponse(Boolean.TRUE, "You successfully deleted tag"); + } + + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to delete this tag"); + + throw new UnauthorizedException(apiResponse); + } } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java index 43eccd13..638fef97 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java @@ -1,26 +1,9 @@ package com.sopromadze.blogapi.service.impl; -import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; -import static com.sopromadze.blogapi.utils.AppConstants.ID; -import static com.sopromadze.blogapi.utils.AppConstants.TODO; -import static com.sopromadze.blogapi.utils.AppConstants.USER; -import static com.sopromadze.blogapi.utils.AppConstants.USERNAME; -import static com.sopromadze.blogapi.utils.AppConstants.YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION; - -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.BadRequestException; import com.sopromadze.blogapi.exception.ResourceNotFoundException; import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.todo.Todo; +import com.sopromadze.blogapi.model.Todo; import com.sopromadze.blogapi.model.user.User; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; @@ -29,10 +12,25 @@ import com.sopromadze.blogapi.security.UserPrincipal; import com.sopromadze.blogapi.service.TodoService; import com.sopromadze.blogapi.utils.AppConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; + +import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; +import static com.sopromadze.blogapi.utils.AppConstants.ID; +import static com.sopromadze.blogapi.utils.AppConstants.TODO; +import static com.sopromadze.blogapi.utils.AppConstants.USER; +import static com.sopromadze.blogapi.utils.AppConstants.USERNAME; +import static com.sopromadze.blogapi.utils.AppConstants.YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION; @Service public class TodoServiceImpl implements TodoService { - @Autowired private TodoRepository todoRepository; @@ -43,18 +41,17 @@ public class TodoServiceImpl implements TodoService { @Override public Todo completeTodo(Long id, UserPrincipal currentUser) { Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); - + User user = userRepository.findByUsername(currentUser.getUsername()) .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); - + if (todo.getUser().getId().equals(user.getId())) { todo.setCompleted(Boolean.TRUE); - Todo result = todoRepository.save(todo); - return result; + return todoRepository.save(todo); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - + throw new UnauthorizedException(apiResponse); } @@ -65,12 +62,11 @@ public Todo unCompleteTodo(Long id, UserPrincipal currentUser) { .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); if (todo.getUser().getId().equals(user.getId())) { todo.setCompleted(Boolean.FALSE); - Todo result = todoRepository.save(todo); - return result; + return todoRepository.save(todo); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - + throw new UnauthorizedException(apiResponse); } @@ -80,7 +76,7 @@ public PagedResponse getAllTodos(UserPrincipal currentUser, int page, int Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); Page todos = todoRepository.findByCreatedBy(currentUser.getId(), pageable); - + List content = todos.getNumberOfElements() == 0 ? Collections.emptyList() : todos.getContent(); return new PagedResponse<>(content, todos.getNumber(), todos.getSize(), todos.getTotalElements(), @@ -92,8 +88,7 @@ public Todo addTodo(Todo todo, UserPrincipal currentUser) { User user = userRepository.findByUsername(currentUser.getUsername()) .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); todo.setUser(user); - Todo result = todoRepository.save(todo); - return result; + return todoRepository.save(todo); } @Override @@ -101,13 +96,13 @@ public Todo getTodo(Long id, UserPrincipal currentUser) { User user = userRepository.findByUsername(currentUser.getUsername()) .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); - - if(todo.getUser().getId().equals(user.getId())) { + + if (todo.getUser().getId().equals(user.getId())) { return todo; } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - + throw new UnauthorizedException(apiResponse); } @@ -119,12 +114,11 @@ public Todo updateTodo(Long id, Todo newTodo, UserPrincipal currentUser) { if (todo.getUser().getId().equals(user.getId())) { todo.setTitle(newTodo.getTitle()); todo.setCompleted(newTodo.getCompleted()); - Todo result = todoRepository.save(todo); - return result; + return todoRepository.save(todo); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - + throw new UnauthorizedException(apiResponse); } @@ -138,9 +132,9 @@ public ApiResponse deleteTodo(Long id, UserPrincipal currentUser) { todoRepository.deleteById(id); return new ApiResponse(Boolean.TRUE, "You successfully deleted todo"); } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION); - + throw new UnauthorizedException(apiResponse); } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java index a27ff271..65d8e41d 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java @@ -1,14 +1,5 @@ package com.sopromadze.blogapi.service.impl; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; - import com.sopromadze.blogapi.exception.AccessDeniedException; import com.sopromadze.blogapi.exception.AppException; import com.sopromadze.blogapi.exception.BadRequestException; @@ -30,6 +21,14 @@ import com.sopromadze.blogapi.repository.UserRepository; import com.sopromadze.blogapi.security.UserPrincipal; import com.sopromadze.blogapi.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; @Service public class UserServiceImpl implements UserService { @@ -93,8 +92,7 @@ public User addUser(User user) { user.setRoles(roles); user.setPassword(passwordEncoder.encode(user.getPassword())); - User result = userRepository.save(user); - return result; + return userRepository.save(user); } @Override @@ -111,8 +109,7 @@ public User updateUser(User newUser, String username, UserPrincipal currentUser) user.setWebsite(newUser.getWebsite()); user.setCompany(newUser.getCompany()); - User updatedUser = userRepository.save(user); - return updatedUser; + return userRepository.save(user); } @@ -125,11 +122,12 @@ public User updateUser(User newUser, String username, UserPrincipal currentUser) public ApiResponse deleteUser(String username, UserPrincipal currentUser) { User user = userRepository.findByUsername(username) .orElseThrow(() -> new ResourceNotFoundException("User", "id", username)); - if (!user.getId().equals(currentUser.getId()) || !currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { + if (!user.getId().equals(currentUser.getId()) || !currentUser.getAuthorities() + .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to delete profile of: " + username); throw new AccessDeniedException(apiResponse); } - + userRepository.deleteById(user.getId()); return new ApiResponse(Boolean.TRUE, "You successfully deleted profile of: " + username); @@ -179,13 +177,12 @@ public UserProfile setOrUpdateInfo(UserPrincipal currentUser, InfoRequest infoRe Long postCount = postRepository.countByCreatedBy(updatedUser.getId()); - UserProfile userProfile = new UserProfile(updatedUser.getId(), updatedUser.getUsername(), + return new UserProfile(updatedUser.getId(), updatedUser.getUsername(), updatedUser.getFirstName(), updatedUser.getLastName(), updatedUser.getCreatedAt(), updatedUser.getEmail(), updatedUser.getAddress(), updatedUser.getPhone(), updatedUser.getWebsite(), updatedUser.getCompany(), postCount); - return userProfile; } - + ApiResponse apiResponse = new ApiResponse(Boolean.FALSE, "You don't have permission to update users profile", HttpStatus.FORBIDDEN); throw new AccessDeniedException(apiResponse); } diff --git a/src/main/java/com/sopromadze/blogapi/utils/AppConstants.java b/src/main/java/com/sopromadze/blogapi/utils/AppConstants.java index cea9424a..19df8f75 100644 --- a/src/main/java/com/sopromadze/blogapi/utils/AppConstants.java +++ b/src/main/java/com/sopromadze/blogapi/utils/AppConstants.java @@ -1,31 +1,31 @@ package com.sopromadze.blogapi.utils; public class AppConstants { - public static final String DEFAULT_PAGE_NUMBER = "0"; - - public static final String DEFAULT_PAGE_SIZE = "30"; - - public static final int MAX_PAGE_SIZE = 30; - - public static final String CREATED_AT = "createdAt"; - - public static final String ID = "id"; - - public static final String PHOTO = "Photo"; - - public static final String ALBUM = "Album"; - - public static final String USERNAME = "username"; - - public static final String USER = "User"; - - public static final String CATEGORY = "Category"; - - public static final String TAG = "Tag"; - - public static final String POST = "Post"; - - public static final String TODO = "ToDo"; - - public static final String YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION = "You don't have permission to make this operation"; + public static final String DEFAULT_PAGE_NUMBER = "0"; + + public static final String DEFAULT_PAGE_SIZE = "30"; + + public static final int MAX_PAGE_SIZE = 30; + + public static final String CREATED_AT = "createdAt"; + + public static final String ID = "id"; + + public static final String PHOTO = "Photo"; + + public static final String ALBUM = "Album"; + + public static final String USERNAME = "username"; + + public static final String USER = "User"; + + public static final String CATEGORY = "Category"; + + public static final String TAG = "Tag"; + + public static final String POST = "Post"; + + public static final String TODO = "ToDo"; + + public static final String YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION = "You don't have permission to make this operation"; } diff --git a/src/main/java/com/sopromadze/blogapi/utils/AppUtils.java b/src/main/java/com/sopromadze/blogapi/utils/AppUtils.java index b1c9e116..fccdf832 100644 --- a/src/main/java/com/sopromadze/blogapi/utils/AppUtils.java +++ b/src/main/java/com/sopromadze/blogapi/utils/AppUtils.java @@ -1,21 +1,20 @@ package com.sopromadze.blogapi.utils; -import org.springframework.http.HttpStatus; - import com.sopromadze.blogapi.exception.BlogapiException; +import org.springframework.http.HttpStatus; public class AppUtils { public static void validatePageNumberAndSize(int page, int size) { - if(page < 0) { - throw new BlogapiException(HttpStatus.BAD_REQUEST, "Page number cannot be less than zero."); - } + if (page < 0) { + throw new BlogapiException(HttpStatus.BAD_REQUEST, "Page number cannot be less than zero."); + } - if(size < 0) { - throw new BlogapiException(HttpStatus.BAD_REQUEST, "Size number cannot be less than zero."); - } + if (size < 0) { + throw new BlogapiException(HttpStatus.BAD_REQUEST, "Size number cannot be less than zero."); + } - if(size > AppConstants.MAX_PAGE_SIZE) { - throw new BlogapiException(HttpStatus.BAD_REQUEST, "Page size must not be greater than " + AppConstants.MAX_PAGE_SIZE); - } - } + if (size > AppConstants.MAX_PAGE_SIZE) { + throw new BlogapiException(HttpStatus.BAD_REQUEST, "Page size must not be greater than " + AppConstants.MAX_PAGE_SIZE); + } + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2caf73ae..d7d7b14c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,19 +1,12 @@ -spring.jpa.hibernate.ddl-auto = none -spring.datasource.url = jdbc:mysql://localhost:3306/blogapi?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true -spring.datasource.username = root -spring.datasource.password = root - -spring.jpa.show-sql = true - -spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect - -app.jwtSecret = secret - +spring.jpa.hibernate.ddl-auto=none +spring.datasource.url=jdbc:mysql://localhost:3306/blogapi?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true +spring.datasource.username=root +spring.datasource.password=root +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +app.jwtSecret=secret # Expiration in milliseconds - 1 Hour -app.jwtExpirationInMs = 3600000 - - -spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false -spring.jackson.time-zone = UTC - -cors.allowedOrings=* \ No newline at end of file +app.jwtExpirationInMs=3600000 +spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false +spring.jackson.time-zone=UTC +cors.allowedOrings=* diff --git a/src/test/java/com/sopromadze/blogapi/AbstractTest.java b/src/test/java/com/sopromadze/blogapi/AbstractTest.java index 01f7f5d2..cf51d6a7 100644 --- a/src/test/java/com/sopromadze/blogapi/AbstractTest.java +++ b/src/test/java/com/sopromadze/blogapi/AbstractTest.java @@ -1,10 +1,5 @@ package com.sopromadze.blogapi; -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; - -import javax.annotation.PostConstruct; -import javax.servlet.Filter; - import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -14,6 +9,11 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; +import javax.annotation.PostConstruct; +import javax.servlet.Filter; + +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; + @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = BlogApiApplication.class) @WebAppConfiguration diff --git a/src/test/java/com/sopromadze/blogapi/BlogApiApplicationTests.java b/src/test/java/com/sopromadze/blogapi/BlogApiApplicationTests.java index c2938f48..b1247c5c 100644 --- a/src/test/java/com/sopromadze/blogapi/BlogApiApplicationTests.java +++ b/src/test/java/com/sopromadze/blogapi/BlogApiApplicationTests.java @@ -9,8 +9,8 @@ @SpringBootTest(classes = BlogApiApplication.class) public class BlogApiApplicationTests { - @Test - public void contextLoads() { - } + @Test + public void contextLoads() { + } } diff --git a/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java b/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java index 9dc6da08..6c5558f3 100644 --- a/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java +++ b/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java @@ -1,38 +1,38 @@ package com.sopromadze.blogapi.model.album; +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.utils.TestUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.junit4.SpringRunner; -import com.sopromadze.blogapi.utils.TestUtils; - @RunWith(SpringRunner.class) public class AlbumTest { - + private Album album; - + @Before public void setup() { album = TestUtils.createAlbum(); } - + @Test public void getIdTest() { Assert.assertNotNull("id can not be null", album.getId()); } - + @Test public void getTitleTest() { Assert.assertNotNull("title can not be null", album.getTitle()); } - + @Test public void getUserTest() { Assert.assertNotNull("user can not be null", album.getUser()); } - + @Test public void getPhotoTest() { Assert.assertNotNull("user can not be null", album.getPhoto()); diff --git a/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java b/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java index e29b3315..55f65d2a 100644 --- a/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java +++ b/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java @@ -1,27 +1,27 @@ package com.sopromadze.blogapi.utils; -import java.util.Arrays; - -import com.sopromadze.blogapi.model.album.Album; -import com.sopromadze.blogapi.model.photo.Photo; +import com.sopromadze.blogapi.model.Album; +import com.sopromadze.blogapi.model.Photo; import com.sopromadze.blogapi.model.user.User; +import java.util.Arrays; + public class TestUtils { - + public static Album createAlbum() { Album album = new Album(); - + album.setId(Long.valueOf(1)); album.setTitle("album"); album.setUser(createUser()); album.setPhoto(Arrays.asList(TestUtils.createPhoto())); - + return album; } - + public static User createUser() { User user = new User(); - + user.setId(Long.valueOf(1)); user.setFirstName("admin"); user.setLastName("admin"); @@ -29,15 +29,15 @@ public static User createUser() { user.setUsername("admin"); user.setPassword("password"); user.setWebsite("site.com"); - + return user; } - + public static Photo createPhoto() { Photo photo = new Photo(); - + photo.setId(Long.valueOf(1)); - + return photo; } } From e02046eb01e134646df546d1e374596cc21e2918 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 00:55:45 +0200 Subject: [PATCH 02/20] clean pom --- pom.xml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pom.xml b/pom.xml index 79747541..9dd103b1 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,6 @@ 2.3.5 - org.springframework.boot spring-boot-devtools @@ -95,13 +94,6 @@ spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-test - test - - org.springframework.boot spring-boot-starter-security @@ -140,13 +132,6 @@ commons-lang3 - - org.modelmapper - modelmapper - 2.3.1 - - - From fac9d280fd7de4c51f7c7afff2555fa3c332567e Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 00:56:08 +0200 Subject: [PATCH 03/20] updated greetings action --- .github/workflows/greetings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index c691b593..4592ff12 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -1,6 +1,6 @@ name: Greetings -on: [pull_request, issues] +on: [pull_request_target, issues] jobs: greeting: From 03e73e7c1ac18ff76f394e779365496bb66a9efe Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 01:08:40 +0200 Subject: [PATCH 04/20] add lombok to pom --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 9dd103b1..eaeb0012 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,13 @@ runtime + + org.projectlombok + lombok + 1.18.12 + provided + + org.springframework.boot spring-boot-starter-web From 64ed9c32426681d478066a58e12a0e43338127bf Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 01:26:38 +0200 Subject: [PATCH 05/20] Update pom.xml --- pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pom.xml b/pom.xml index a5471fc5..06f63749 100644 --- a/pom.xml +++ b/pom.xml @@ -48,11 +48,6 @@ org.springframework.boot spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-web - org.springframework.boot From fb72ea41a7fab310cae16f9e4fb8f4d52325207d Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 03:49:51 +0200 Subject: [PATCH 06/20] updated docker-compose --- Dockerfile | 2 +- data/blogapi.sql | 192 +++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 31 +++++--- 3 files changed, 212 insertions(+), 13 deletions(-) create mode 100644 data/blogapi.sql diff --git a/Dockerfile b/Dockerfile index ea74f862..e7d65cce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:11-jre-slim +FROM adoptopenjdk/openjdk11:alpine-jre VOLUME /tmp ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar diff --git a/data/blogapi.sql b/data/blogapi.sql new file mode 100644 index 00000000..5cc9ced8 --- /dev/null +++ b/data/blogapi.sql @@ -0,0 +1,192 @@ +USE blogapi; + +UNLOCK TABLES; + +DROP TABLE IF EXISTS `post_tag`; +DROP TABLE IF EXISTS `tags`; +DROP TABLE IF EXISTS `user_role`; +DROP TABLE IF EXISTS `roles`; +DROP TABLE IF EXISTS `comments`; +DROP TABLE IF EXISTS `posts`; +DROP TABLE IF EXISTS `photos`; +DROP TABLE IF EXISTS `albums`; +DROP TABLE IF EXISTS `todos`; +DROP TABLE IF EXISTS `users`; +DROP TABLE IF EXISTS `address`; +DROP TABLE IF EXISTS `company`; +DROP TABLE IF EXISTS `geo`; + +CREATE TABLE `tags` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned NOT NULL, + `updated_by` bigint(19) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `geo` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `lat` varchar(255), + `lng` varchar(255), + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `company` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255), + `catch_phrase` varchar(255), + `bs` varchar(255), + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `address` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `street` varchar(255), + `suite` varchar(255), + `city` varchar(255), + `zipcode` varchar(255), + `geo_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk_geo` (`geo_id`), + CONSTRAINT `fk_geo` FOREIGN KEY (`geo_id`) REFERENCES `geo` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `users` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(255) NOT NULL, + `last_name` varchar(255) NOT NULL, + `username` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `address_id` bigint(19) unsigned DEFAULT NULL, + `phone` varchar(255), + `website` varchar(255), + `company_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `fk_address` (`address_id`), + KEY `fk_company` (`company_id`), + CONSTRAINT `fk_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `fk_company` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `todos` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `completed` boolean default false, + `user_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk_user_todos` (`user_id`), + CONSTRAINT `fk_user_todos` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `albums` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `user_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk_user_album` (`user_id`), + CONSTRAINT `fk_user_album` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `photos` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `url` varchar(255) NOT NULL, + `thumbnail_url` varchar(255) NOT NULL, + `album_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk_album` (`album_id`), + CONSTRAINT `fk_album` FOREIGN KEY (`album_id`) REFERENCES `albums` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `posts` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `body` text NOT NULL, + `user_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned DEFAULT NULL, + `updated_by` bigint(19) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk_user_post` (`user_id`), + CONSTRAINT `fk_user_post` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `post_tag` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `post_id` bigint(19) unsigned NOT NULL, + `tag_id` bigint(19) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `fk_posttag_post_id` (`post_id`), + KEY `fk_posttag_tag_id` (`tag_id`), + CONSTRAINT `fk_posttag_post_id` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`), + CONSTRAINT `fk_posttag_tag_id` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `comments` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `body` text NOT NULL, + `post_id` bigint(19) unsigned DEFAULT NULL, + `user_id` bigint(19) unsigned DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint(19) unsigned NOT NULL, + `updated_by` bigint(19) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `fk_comment_post` (`post_id`), + KEY `fk_comment_user` (`user_id`), + CONSTRAINT `fk_comment_post` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`), + CONSTRAINT `fk_comment_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `roles` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `user_role` ( + `id` bigint(19) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(19) unsigned NOT NULL, + `role_id` bigint(19) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `fk_security_user_id` (`user_id`), + KEY `fk_security_role_id` (`role_id`), + CONSTRAINT `fk_security_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `fk_security_role_id` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +LOCK TABLES `roles` WRITE; +INSERT INTO `roles` VALUES (1,'ROLE_ADMIN'),(2,'ROLE_USER'); +UNLOCK TABLES; diff --git a/docker-compose.yml b/docker-compose.yml index c098f3df..9bd9053e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,36 @@ -version: '3' +version: '3.8' services: - mysql: + db: image: mysql + container_name: blogapi-db restart: always environment: MYSQL_DATABASE: 'blogapi' - MYSQL_USER: 'root' MYSQL_PASSWORD: 'root' MYSQL_ROOT_PASSWORD: 'root' ports: - - '3306' + - '3306:3306' networks: - - production-network + - blogapi-network + healthcheck: + test: "/usr/bin/mysql --user=root --password=root --execute \"SHOW DATABASES;\"" + interval: 2s + timeout: 20s + retries: 10 + volumes: + - ./data:/docker-entrypoint-initdb.d application: + container_name: blogapi-application build: - dockerfile: ./Dockerfile - context: . - image: michel-eckhardt/spring-boot-blog - container_name: spring-boot-blog + context: ./ + dockerfile: Dockerfile ports: - "8080:8080" networks: - - production-network + - blogapi-network depends_on: - - "mysql" + - "db" networks: - production-network: + blogapi-network: + name: blogapi-network driver: bridge From f0088ab916b116754f067dd748ba6400c4c148ff Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 03:50:18 +0200 Subject: [PATCH 07/20] added applications.yml --- ...ion.properties => _application.properties} | 0 src/main/resources/application.yml | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+) rename src/main/resources/{application.properties => _application.properties} (100%) create mode 100644 src/main/resources/application.yml diff --git a/src/main/resources/application.properties b/src/main/resources/_application.properties similarity index 100% rename from src/main/resources/application.properties rename to src/main/resources/_application.properties diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 00000000..ef6d7e3d --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,23 @@ +spring: + datasource: + url: jdbc:mysql://blogapi-db:3306/blogapi?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true + username: root + password: root + jpa: + hibernate: + ddl-auto: none + show-sql: true + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5Dialect + jackson: + serialization: + WRITE_DATES_AS_TIMESTAMPS: false + time-zone: UTC + +app: + jwtSecret: secret + jwtExpirationInMs: 3600000 + +cors: + allowedOrings: '*' From 261173b436a39598fd383584cb2fc40adf342b95 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 03:50:40 +0200 Subject: [PATCH 08/20] added lombok EqualsAndHashCode --- .../com/sopromadze/blogapi/model/Album.java | 2 + .../sopromadze/blogapi/model/Category.java | 2 + .../com/sopromadze/blogapi/model/Comment.java | 70 ++++++++++--------- .../com/sopromadze/blogapi/model/Photo.java | 2 + .../com/sopromadze/blogapi/model/Post.java | 2 + .../com/sopromadze/blogapi/model/Tag.java | 2 + .../com/sopromadze/blogapi/model/Todo.java | 2 + .../blogapi/model/audit/UserDateAudit.java | 2 + .../blogapi/model/user/Address.java | 2 + .../blogapi/model/user/Company.java | 2 + .../sopromadze/blogapi/model/user/Geo.java | 2 + .../sopromadze/blogapi/model/user/User.java | 2 + .../blogapi/payload/AlbumResponse.java | 2 + .../blogapi/payload/UserDateAuditPayload.java | 2 + .../com/sopromadze/blogapi/AbstractTest.java | 35 ---------- .../blogapi/model/album/AlbumTest.java | 40 ----------- .../sopromadze/blogapi/utils/TestUtils.java | 43 ------------ 17 files changed, 62 insertions(+), 152 deletions(-) delete mode 100644 src/test/java/com/sopromadze/blogapi/AbstractTest.java delete mode 100644 src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java delete mode 100644 src/test/java/com/sopromadze/blogapi/utils/TestUtils.java diff --git a/src/main/java/com/sopromadze/blogapi/model/Album.java b/src/main/java/com/sopromadze/blogapi/model/Album.java index 72841c7c..311d5991 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Album.java +++ b/src/main/java/com/sopromadze/blogapi/model/Album.java @@ -4,6 +4,7 @@ import com.sopromadze.blogapi.model.audit.UserDateAudit; import com.sopromadze.blogapi.model.user.User; import lombok.Data; +import lombok.EqualsAndHashCode; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -22,6 +23,7 @@ import java.util.Collections; import java.util.List; +@EqualsAndHashCode(callSuper = true) @Entity @Data @Table(name = "albums", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) diff --git a/src/main/java/com/sopromadze/blogapi/model/Category.java b/src/main/java/com/sopromadze/blogapi/model/Category.java index 9d2358c1..102c6e39 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Category.java +++ b/src/main/java/com/sopromadze/blogapi/model/Category.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.sopromadze.blogapi.model.audit.UserDateAudit; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.CascadeType; @@ -18,6 +19,7 @@ import java.util.Collections; import java.util.List; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/model/Comment.java b/src/main/java/com/sopromadze/blogapi/model/Comment.java index 4b790c5a..d9d21972 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Comment.java +++ b/src/main/java/com/sopromadze/blogapi/model/Comment.java @@ -4,6 +4,7 @@ import com.sopromadze.blogapi.model.audit.UserDateAudit; import com.sopromadze.blogapi.model.user.User; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.Column; @@ -19,52 +20,53 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor @Table(name = "comments") public class Comment extends UserDateAudit { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; - @Column(name = "name") - @NotBlank - @Size(min = 4, max = 50) - private String name; + @Column(name = "name") + @NotBlank + @Size(min = 4, max = 50) + private String name; - @Column(name = "email") - @NotBlank - @Email - @Size(min = 4, max = 50) - private String email; + @Column(name = "email") + @NotBlank + @Email + @Size(min = 4, max = 50) + private String email; - @Column(name = "body") - @NotBlank - @Size(min = 10, message = "Comment body must be minimum 10 characters") - private String body; + @Column(name = "body") + @NotBlank + @Size(min = 10, message = "Comment body must be minimum 10 characters") + private String body; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; - public Comment(@NotBlank @Size(min = 10, message = "Comment body must be minimum 10 characters") String body) { - this.body = body; - } + public Comment(@NotBlank @Size(min = 10, message = "Comment body must be minimum 10 characters") String body) { + this.body = body; + } - @JsonIgnore - public Post getPost() { - return post; - } + @JsonIgnore + public Post getPost() { + return post; + } - @JsonIgnore - public User getUser() { - return user; - } + @JsonIgnore + public User getUser() { + return user; + } } diff --git a/src/main/java/com/sopromadze/blogapi/model/Photo.java b/src/main/java/com/sopromadze/blogapi/model/Photo.java index c65f6bff..c58f0e06 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Photo.java +++ b/src/main/java/com/sopromadze/blogapi/model/Photo.java @@ -4,6 +4,7 @@ import com.sopromadze.blogapi.model.Album; import com.sopromadze.blogapi.model.audit.UserDateAudit; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.Column; @@ -18,6 +19,7 @@ import javax.persistence.UniqueConstraint; import javax.validation.constraints.NotBlank; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/model/Post.java b/src/main/java/com/sopromadze/blogapi/model/Post.java index c654a58f..6b97dbcf 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Post.java +++ b/src/main/java/com/sopromadze/blogapi/model/Post.java @@ -6,6 +6,7 @@ import com.sopromadze.blogapi.model.audit.UserDateAudit; import com.sopromadze.blogapi.model.user.User; import lombok.Data; +import lombok.EqualsAndHashCode; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -25,6 +26,7 @@ import java.util.Collections; import java.util.List; +@EqualsAndHashCode(callSuper = true) @Entity @Data @Table(name = "posts", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) diff --git a/src/main/java/com/sopromadze/blogapi/model/Tag.java b/src/main/java/com/sopromadze/blogapi/model/Tag.java index a7b64ccd..a3cbd193 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Tag.java +++ b/src/main/java/com/sopromadze/blogapi/model/Tag.java @@ -4,6 +4,7 @@ import com.sopromadze.blogapi.model.audit.UserDateAudit; import com.sopromadze.blogapi.model.Post; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.Column; @@ -20,6 +21,7 @@ import java.util.Collections; import java.util.List; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/model/Todo.java b/src/main/java/com/sopromadze/blogapi/model/Todo.java index 06840c1c..7fed93d1 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Todo.java +++ b/src/main/java/com/sopromadze/blogapi/model/Todo.java @@ -4,6 +4,7 @@ import com.sopromadze.blogapi.model.audit.UserDateAudit; import com.sopromadze.blogapi.model.user.User; import lombok.Data; +import lombok.EqualsAndHashCode; import javax.persistence.Column; import javax.persistence.Entity; @@ -17,6 +18,7 @@ import javax.persistence.UniqueConstraint; import javax.validation.constraints.NotBlank; +@EqualsAndHashCode(callSuper = true) @Entity @Data @Table(name = "todos", uniqueConstraints = { @UniqueConstraint(columnNames = { "title" }) }) diff --git a/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java b/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java index 245bcf96..10644bd5 100644 --- a/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java +++ b/src/main/java/com/sopromadze/blogapi/model/audit/UserDateAudit.java @@ -2,12 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; +import lombok.EqualsAndHashCode; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.LastModifiedBy; import javax.persistence.Column; import javax.persistence.MappedSuperclass; +@EqualsAndHashCode(callSuper = true) @MappedSuperclass @Data @JsonIgnoreProperties( diff --git a/src/main/java/com/sopromadze/blogapi/model/user/Address.java b/src/main/java/com/sopromadze/blogapi/model/user/Address.java index 6c460d35..f686bbbf 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/Address.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/Address.java @@ -4,6 +4,7 @@ import com.sopromadze.blogapi.model.audit.UserDateAudit; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.CascadeType; @@ -17,6 +18,7 @@ import javax.persistence.Table; import java.time.Instant; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/model/user/Company.java b/src/main/java/com/sopromadze/blogapi/model/user/Company.java index 541d1073..7cc93a2f 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/Company.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/Company.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.sopromadze.blogapi.model.audit.UserDateAudit; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.Column; @@ -14,6 +15,7 @@ import javax.persistence.Table; import java.time.Instant; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/model/user/Geo.java b/src/main/java/com/sopromadze/blogapi/model/user/Geo.java index e7cfaad9..f2845e22 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/Geo.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/Geo.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.sopromadze.blogapi.model.audit.UserDateAudit; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import javax.persistence.Column; @@ -14,6 +15,7 @@ import javax.persistence.Table; import java.time.Instant; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/model/user/User.java b/src/main/java/com/sopromadze/blogapi/model/user/User.java index 81ff6287..90f2e489 100644 --- a/src/main/java/com/sopromadze/blogapi/model/user/User.java +++ b/src/main/java/com/sopromadze/blogapi/model/user/User.java @@ -9,6 +9,7 @@ import com.sopromadze.blogapi.model.role.Role; import com.sopromadze.blogapi.model.Todo; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import org.hibernate.annotations.NaturalId; @@ -33,6 +34,7 @@ import java.util.Collections; import java.util.List; +@EqualsAndHashCode(callSuper = true) @Entity @Data @NoArgsConstructor diff --git a/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java b/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java index bd408037..ea57f7df 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java +++ b/src/main/java/com/sopromadze/blogapi/payload/AlbumResponse.java @@ -5,11 +5,13 @@ import com.sopromadze.blogapi.model.Photo; import com.sopromadze.blogapi.model.user.User; import lombok.Data; +import lombok.EqualsAndHashCode; import java.util.ArrayList; import java.util.Collections; import java.util.List; +@EqualsAndHashCode(callSuper = true) @Data @JsonInclude(Include.NON_NULL) public class AlbumResponse extends UserDateAuditPayload { diff --git a/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java b/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java index b112bea5..834f095d 100644 --- a/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java +++ b/src/main/java/com/sopromadze/blogapi/payload/UserDateAuditPayload.java @@ -1,7 +1,9 @@ package com.sopromadze.blogapi.payload; import lombok.Data; +import lombok.EqualsAndHashCode; +@EqualsAndHashCode(callSuper = true) @Data public abstract class UserDateAuditPayload extends DateAuditPayload { private Long createdBy; diff --git a/src/test/java/com/sopromadze/blogapi/AbstractTest.java b/src/test/java/com/sopromadze/blogapi/AbstractTest.java deleted file mode 100644 index cf51d6a7..00000000 --- a/src/test/java/com/sopromadze/blogapi/AbstractTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sopromadze.blogapi; - -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import javax.annotation.PostConstruct; -import javax.servlet.Filter; - -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = BlogApiApplication.class) -@WebAppConfiguration -public abstract class AbstractTest { - protected MockMvc mvc; - - @Autowired - protected WebApplicationContext webApplicationContext; - - @Autowired - protected Filter springSecurityFilterChain; - - @PostConstruct - protected void setUp() { - mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity(springSecurityFilterChain)) - .build(); - } - -} diff --git a/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java b/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java deleted file mode 100644 index 6c5558f3..00000000 --- a/src/test/java/com/sopromadze/blogapi/model/album/AlbumTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sopromadze.blogapi.model.album; - -import com.sopromadze.blogapi.model.Album; -import com.sopromadze.blogapi.utils.TestUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -public class AlbumTest { - - private Album album; - - @Before - public void setup() { - album = TestUtils.createAlbum(); - } - - @Test - public void getIdTest() { - Assert.assertNotNull("id can not be null", album.getId()); - } - - @Test - public void getTitleTest() { - Assert.assertNotNull("title can not be null", album.getTitle()); - } - - @Test - public void getUserTest() { - Assert.assertNotNull("user can not be null", album.getUser()); - } - - @Test - public void getPhotoTest() { - Assert.assertNotNull("user can not be null", album.getPhoto()); - } -} diff --git a/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java b/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java deleted file mode 100644 index 55f65d2a..00000000 --- a/src/test/java/com/sopromadze/blogapi/utils/TestUtils.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.sopromadze.blogapi.utils; - -import com.sopromadze.blogapi.model.Album; -import com.sopromadze.blogapi.model.Photo; -import com.sopromadze.blogapi.model.user.User; - -import java.util.Arrays; - -public class TestUtils { - - public static Album createAlbum() { - Album album = new Album(); - - album.setId(Long.valueOf(1)); - album.setTitle("album"); - album.setUser(createUser()); - album.setPhoto(Arrays.asList(TestUtils.createPhoto())); - - return album; - } - - public static User createUser() { - User user = new User(); - - user.setId(Long.valueOf(1)); - user.setFirstName("admin"); - user.setLastName("admin"); - user.setEmail("admin@site.com"); - user.setUsername("admin"); - user.setPassword("password"); - user.setWebsite("site.com"); - - return user; - } - - public static Photo createPhoto() { - Photo photo = new Photo(); - - photo.setId(Long.valueOf(1)); - - return photo; - } -} From cec535d9336cda2997ec3ae388b3c2d3fa59bbd3 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Mon, 7 Sep 2020 04:05:39 +0200 Subject: [PATCH 09/20] build --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 06f63749..6b948751 100644 --- a/pom.xml +++ b/pom.xml @@ -159,5 +159,4 @@ - From d493b07b489e2da60d86a4ae7c12ff347b40c3f2 Mon Sep 17 00:00:00 2001 From: ABDERRAOUF MAKHLOUF Date: Wed, 9 Sep 2020 00:40:35 +0200 Subject: [PATCH 10/20] chore() refactor code --- .../blogapi/controller/AuthController.java | 4 ++-- .../blogapi/controller/TodoController.java | 2 +- .../com/sopromadze/blogapi/model/Photo.java | 1 - .../blogapi/repository/UserRepository.java | 11 ++++++++++ .../service/impl/AlbumServiceImpl.java | 16 +++++---------- .../service/impl/CategoryServiceImpl.java | 4 ++-- .../service/impl/CommentServiceImpl.java | 3 +-- .../impl/CustomUserDetailsServiceImpl.java | 2 +- .../blogapi/service/impl/PostServiceImpl.java | 13 +++++------- .../blogapi/service/impl/TagServiceImpl.java | 4 ++-- .../blogapi/service/impl/TodoServiceImpl.java | 20 ++++++------------- .../blogapi/service/impl/UserServiceImpl.java | 12 ++++------- 12 files changed, 40 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/sopromadze/blogapi/controller/AuthController.java b/src/main/java/com/sopromadze/blogapi/controller/AuthController.java index fce9d3b0..5d49753d 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/AuthController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/AuthController.java @@ -64,11 +64,11 @@ public ResponseEntity authenticateUser(@Valid @Reques @PostMapping("/signup") public ResponseEntity registerUser(@Valid @RequestBody SignUpRequest signUpRequest) { - if (userRepository.existsByUsername(signUpRequest.getUsername())) { + if (Boolean.TRUE.equals(userRepository.existsByUsername(signUpRequest.getUsername()))) { throw new BlogapiException(HttpStatus.BAD_REQUEST, "Username is already taken"); } - if (userRepository.existsByEmail(signUpRequest.getEmail())) { + if (Boolean.TRUE.equals(userRepository.existsByEmail(signUpRequest.getEmail()))) { throw new BlogapiException(HttpStatus.BAD_REQUEST, "Email is already taken"); } diff --git a/src/main/java/com/sopromadze/blogapi/controller/TodoController.java b/src/main/java/com/sopromadze/blogapi/controller/TodoController.java index ccdf91f1..aeb57789 100644 --- a/src/main/java/com/sopromadze/blogapi/controller/TodoController.java +++ b/src/main/java/com/sopromadze/blogapi/controller/TodoController.java @@ -72,7 +72,7 @@ public ResponseEntity updateTodo(@PathVariable(value = "id") Long id, @Val public ResponseEntity deleteTodo(@PathVariable(value = "id") Long id, @CurrentUser UserPrincipal currentUser) { ApiResponse apiResponse = todoService.deleteTodo(id, currentUser); - return new ResponseEntity(apiResponse, HttpStatus.OK); + return new ResponseEntity<>(apiResponse, HttpStatus.OK); } @PutMapping("/{id}/complete") diff --git a/src/main/java/com/sopromadze/blogapi/model/Photo.java b/src/main/java/com/sopromadze/blogapi/model/Photo.java index c58f0e06..7aaa1d2a 100644 --- a/src/main/java/com/sopromadze/blogapi/model/Photo.java +++ b/src/main/java/com/sopromadze/blogapi/model/Photo.java @@ -1,7 +1,6 @@ package com.sopromadze.blogapi.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.sopromadze.blogapi.model.Album; import com.sopromadze.blogapi.model.audit.UserDateAudit; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java b/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java index ef88331a..94290248 100644 --- a/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java +++ b/src/main/java/com/sopromadze/blogapi/repository/UserRepository.java @@ -1,6 +1,8 @@ package com.sopromadze.blogapi.repository; +import com.sopromadze.blogapi.exception.ResourceNotFoundException; import com.sopromadze.blogapi.model.user.User; +import com.sopromadze.blogapi.security.UserPrincipal; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -18,4 +20,13 @@ public interface UserRepository extends JpaRepository { Boolean existsByEmail(@NotBlank String email); Optional findByUsernameOrEmail(String username, String email); + + default User getUser(UserPrincipal currentUser) { + return getUserByName(currentUser.getUsername()); + } + + default User getUserByName(String username) { + return findByUsername(username) + .orElseThrow(() -> new ResourceNotFoundException("User", "username", username)); + } } diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java index 008196eb..6964008e 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/AlbumServiceImpl.java @@ -37,10 +37,6 @@ public class AlbumServiceImpl implements AlbumService { private static final String ALBUM_STR = "Album"; - private static final String USER_STR = "User"; - - private static final String USERNAME_STR = "username"; - private static final String YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION = "You don't have permission to make this operation"; @Autowired @@ -73,8 +69,7 @@ public PagedResponse getAllAlbums(int page, int size) { @Override public ResponseEntity addAlbum(AlbumRequest albumRequest, UserPrincipal currentUser) { - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); Album album = new Album(); @@ -94,8 +89,7 @@ public ResponseEntity getAlbum(Long id) { @Override public ResponseEntity updateAlbum(Long id, AlbumRequest newAlbum, UserPrincipal currentUser) { Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); if (album.getUser().getId().equals(user.getId()) || currentUser.getAuthorities() .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { album.setTitle(newAlbum.getTitle()); @@ -114,8 +108,7 @@ public ResponseEntity updateAlbum(Long id, AlbumRequest newAlbum, @Override public ResponseEntity deleteAlbum(Long id, UserPrincipal currentUser) { Album album = albumRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(ALBUM_STR, ID, id)); - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); if (album.getUser().getId().equals(user.getId()) || currentUser.getAuthorities() .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { albumRepository.deleteById(id); @@ -127,7 +120,8 @@ public ResponseEntity deleteAlbum(Long id, UserPrincipal currentUse @Override public PagedResponse getUserAlbums(String username, int page, int size) { - User user = userRepository.findByUsername(username).orElseThrow(() -> new ResourceNotFoundException(USER_STR, USERNAME_STR, username)); + User user = userRepository.getUserByName(username); + Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); Page albums = albumRepository.findByCreatedBy(user.getId(), pageable); diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java index cbe392dc..a98064b3 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/CategoryServiceImpl.java @@ -56,7 +56,7 @@ public ResponseEntity addCategory(Category category, UserPrincipal cur } @Override - public ResponseEntity updateCategory(Long id, Category newCategory, UserPrincipal currentUser) throws UnauthorizedException { + public ResponseEntity updateCategory(Long id, Category newCategory, UserPrincipal currentUser) { Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Category", "id", id)); if (category.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities() .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { @@ -69,7 +69,7 @@ public ResponseEntity updateCategory(Long id, Category newCategory, Us } @Override - public ResponseEntity deleteCategory(Long id, UserPrincipal currentUser) throws UnauthorizedException { + public ResponseEntity deleteCategory(Long id, UserPrincipal currentUser) { Category category = categoryRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("category", "id", id)); if (category.getCreatedBy().equals(currentUser.getId()) || currentUser.getAuthorities() .contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java index f09df86d..00258de7 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/CommentServiceImpl.java @@ -62,8 +62,7 @@ public PagedResponse getAllComments(Long postId, int page, int size) { public Comment addComment(CommentRequest commentRequest, Long postId, UserPrincipal currentUser) { Post post = postRepository.findById(postId) .orElseThrow(() -> new ResourceNotFoundException(POST_STR, ID_STR, postId)); - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException("User", "username", currentUser.getUsername())); + User user = userRepository.getUser(currentUser); Comment comment = new Comment(commentRequest.getBody()); comment.setUser(user); comment.setPost(post); diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java index 5014497e..27451513 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/CustomUserDetailsServiceImpl.java @@ -19,7 +19,7 @@ public class CustomUserDetailsServiceImpl implements UserDetailsService, CustomU @Override @Transactional - public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException { + public UserDetails loadUserByUsername(String usernameOrEmail) { User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail) .orElseThrow(() -> new UsernameNotFoundException(String.format("User not found with this username or email: %s", usernameOrEmail))); return UserPrincipal.create(user); diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java index 9ba5fa06..8666ec58 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/PostServiceImpl.java @@ -5,8 +5,8 @@ import com.sopromadze.blogapi.exception.UnauthorizedException; import com.sopromadze.blogapi.model.Category; import com.sopromadze.blogapi.model.Post; -import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.model.Tag; +import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.model.user.User; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; @@ -29,7 +29,6 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -39,7 +38,6 @@ import static com.sopromadze.blogapi.utils.AppConstants.POST; import static com.sopromadze.blogapi.utils.AppConstants.TAG; import static com.sopromadze.blogapi.utils.AppConstants.USER; -import static com.sopromadze.blogapi.utils.AppConstants.USERNAME; @Service public class PostServiceImpl implements PostService { @@ -72,8 +70,7 @@ public PagedResponse getAllPosts(int page, int size) { @Override public PagedResponse getPostsByCreatedBy(String username, int page, int size) { validatePageNumberAndSize(page, size); - User user = userRepository.findByUsername(username) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, username)); + User user = userRepository.getUserByName(username); Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); Page posts = postRepository.findByCreatedBy(user.getId(), pageable); @@ -106,7 +103,7 @@ public PagedResponse getPostsByTag(Long id, int page, int size) { Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, CREATED_AT); - Page posts = postRepository.findByTags(Arrays.asList(tag), pageable); + Page posts = postRepository.findByTags(Collections.singletonList(tag), pageable); List content = posts.getNumberOfElements() == 0 ? Collections.emptyList() : posts.getContent(); @@ -152,7 +149,7 @@ public PostResponse addPost(PostRequest postRequest, UserPrincipal currentUser) Category category = categoryRepository.findById(postRequest.getCategoryId()) .orElseThrow(() -> new ResourceNotFoundException(CATEGORY, ID, postRequest.getCategoryId())); - List tags = new ArrayList< >(postRequest.getTags().size()); + List tags = new ArrayList<>(postRequest.getTags().size()); for (String name : postRequest.getTags()) { Tag tag = tagRepository.findByName(name); @@ -176,7 +173,7 @@ public PostResponse addPost(PostRequest postRequest, UserPrincipal currentUser) postResponse.setBody(newPost.getBody()); postResponse.setCategory(newPost.getCategory().getName()); - List tagNames = new ArrayList< >(newPost.getTags().size()); + List tagNames = new ArrayList<>(newPost.getTags().size()); for (Tag tag : newPost.getTags()) { tagNames.add(tag.getName()); diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java index cb77efae..18488a23 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/TagServiceImpl.java @@ -2,8 +2,8 @@ import com.sopromadze.blogapi.exception.ResourceNotFoundException; import com.sopromadze.blogapi.exception.UnauthorizedException; -import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.model.Tag; +import com.sopromadze.blogapi.model.role.RoleName; import com.sopromadze.blogapi.payload.ApiResponse; import com.sopromadze.blogapi.payload.PagedResponse; import com.sopromadze.blogapi.repository.TagRepository; @@ -37,7 +37,7 @@ public PagedResponse getAllTags(int page, int size) { List content = tags.getNumberOfElements() == 0 ? Collections.emptyList() : tags.getContent(); - return new PagedResponse< >(content, tags.getNumber(), tags.getSize(), tags.getTotalElements(), tags.getTotalPages(), tags.isLast()); + return new PagedResponse<>(content, tags.getNumber(), tags.getSize(), tags.getTotalElements(), tags.getTotalPages(), tags.isLast()); } @Override diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java index 638fef97..9ef3b2e8 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/TodoServiceImpl.java @@ -25,8 +25,6 @@ import static com.sopromadze.blogapi.utils.AppConstants.CREATED_AT; import static com.sopromadze.blogapi.utils.AppConstants.ID; import static com.sopromadze.blogapi.utils.AppConstants.TODO; -import static com.sopromadze.blogapi.utils.AppConstants.USER; -import static com.sopromadze.blogapi.utils.AppConstants.USERNAME; import static com.sopromadze.blogapi.utils.AppConstants.YOU_DON_T_HAVE_PERMISSION_TO_MAKE_THIS_OPERATION; @Service @@ -42,8 +40,7 @@ public class TodoServiceImpl implements TodoService { public Todo completeTodo(Long id, UserPrincipal currentUser) { Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); if (todo.getUser().getId().equals(user.getId())) { todo.setCompleted(Boolean.TRUE); @@ -58,8 +55,7 @@ public Todo completeTodo(Long id, UserPrincipal currentUser) { @Override public Todo unCompleteTodo(Long id, UserPrincipal currentUser) { Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); if (todo.getUser().getId().equals(user.getId())) { todo.setCompleted(Boolean.FALSE); return todoRepository.save(todo); @@ -85,16 +81,14 @@ public PagedResponse getAllTodos(UserPrincipal currentUser, int page, int @Override public Todo addTodo(Todo todo, UserPrincipal currentUser) { - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); todo.setUser(user); return todoRepository.save(todo); } @Override public Todo getTodo(Long id, UserPrincipal currentUser) { - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); if (todo.getUser().getId().equals(user.getId())) { @@ -108,8 +102,7 @@ public Todo getTodo(Long id, UserPrincipal currentUser) { @Override public Todo updateTodo(Long id, Todo newTodo, UserPrincipal currentUser) { - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); if (todo.getUser().getId().equals(user.getId())) { todo.setTitle(newTodo.getTitle()); @@ -124,8 +117,7 @@ public Todo updateTodo(Long id, Todo newTodo, UserPrincipal currentUser) { @Override public ApiResponse deleteTodo(Long id, UserPrincipal currentUser) { - User user = userRepository.findByUsername(currentUser.getUsername()) - .orElseThrow(() -> new ResourceNotFoundException(USER, USERNAME, currentUser.getUsername())); + User user = userRepository.getUser(currentUser); Todo todo = todoRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(TODO, ID, id)); if (todo.getUser().getId().equals(user.getId())) { diff --git a/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java b/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java index 65d8e41d..d740f27b 100644 --- a/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java +++ b/src/main/java/com/sopromadze/blogapi/service/impl/UserServiceImpl.java @@ -64,8 +64,7 @@ public UserIdentityAvailability checkEmailAvailability(String email) { @Override public UserProfile getUserProfile(String username) { - User user = userRepository.findByUsername(username) - .orElseThrow(() -> new ResourceNotFoundException("User", "username", username)); + User user = userRepository.getUserByName(username); Long postCount = postRepository.countByCreatedBy(user.getId()); @@ -97,8 +96,7 @@ public User addUser(User user) { @Override public User updateUser(User newUser, String username, UserPrincipal currentUser) { - User user = userRepository.findByUsername(username) - .orElseThrow(() -> new ResourceNotFoundException("User", "username", username)); + User user = userRepository.getUserByName(username); if (user.getId().equals(currentUser.getId()) || currentUser.getAuthorities().contains(new SimpleGrantedAuthority(RoleName.ROLE_ADMIN.toString()))) { user.setFirstName(newUser.getFirstName()); @@ -135,8 +133,7 @@ public ApiResponse deleteUser(String username, UserPrincipal currentUser) { @Override public ApiResponse giveAdmin(String username) { - User user = userRepository.findByUsername(username) - .orElseThrow(() -> new ResourceNotFoundException("User", "username", username)); + User user = userRepository.getUserByName(username); List roles = new ArrayList<>(); roles.add(roleRepository.findByName(RoleName.ROLE_ADMIN) .orElseThrow(() -> new AppException("User role not set"))); @@ -149,8 +146,7 @@ public ApiResponse giveAdmin(String username) { @Override public ApiResponse removeAdmin(String username) { - User user = userRepository.findByUsername(username) - .orElseThrow(() -> new ResourceNotFoundException("User", "username", username)); + User user = userRepository.getUserByName(username); List roles = new ArrayList<>(); roles.add( roleRepository.findByName(RoleName.ROLE_USER).orElseThrow(() -> new AppException("User role not set"))); From be6e48a28999348a0eea6487865f7bb9e54a8bfe Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Fri, 13 Nov 2020 22:09:12 +0100 Subject: [PATCH 11/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f705086..2906f0fd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API.svg?branch=development)](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=coma123_Spring-Boot-Blog-REST-API&metric=alert_status)](https://sonarcloud.io/dashboard?id=coma123_Spring-Boot-Blog-REST-API) +[![Build Status](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API.svg?branch=development)](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=coma123_Spring-Boot-Blog-REST-API&metric=alert_status)](https://sonarcloud.io/dashboard?id=coma123_Spring-Boot-Blog-REST-API) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3706/badge)](https://bestpractices.coreinfrastructure.org/projects/3706) # Spring Boot, MySQL, Spring Security, JWT, JPA, Rest API From 67d5dacd91445e609d1df257d8e8f3230e6580b5 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Wed, 17 Mar 2021 13:54:35 +0400 Subject: [PATCH 12/20] Delete .mvn/wrapper directory --- .mvn/wrapper/maven-wrapper.jar | Bin 47610 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 1 - 2 files changed, 1 deletion(-) delete mode 100644 .mvn/wrapper/maven-wrapper.jar delete mode 100644 .mvn/wrapper/maven-wrapper.properties diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 9cc84ea9b4d95453115d0c26488d6a78694e0bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47610 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 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 6c8c0e08..00000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip From 22561dccb244938c3f91e55b0e663e896833d56f Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Sat, 25 Dec 2021 17:38:29 +0100 Subject: [PATCH 13/20] Update greetings.yml --- .github/workflows/greetings.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index eba059d0..5e398432 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -9,5 +9,5 @@ jobs: - uses: actions/first-interaction@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: 'Welcome to Spring-Boot-Blog-REST-API community! Thanks so much for creating your first issue :)' - pr-message: 'Thanks so much for creating your first PR, the Spring-Boot-Blog-REST-API community thanks you :)' + issue-message: 'Welcome @${{ github.actor }} to Spring-Boot-Blog-REST-API community! Thanks so much for creating your first issue :)' + pr-message: 'Thanks so much @${{ github.actor }} for creating your first PR, the Spring-Boot-Blog-REST-API community thanks you :)' From 15c7f8ed467833397d2774cbe90733bb200b6090 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Sat, 25 Dec 2021 17:41:35 +0100 Subject: [PATCH 14/20] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6b948751..1a2dfb50 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.3.4.RELEASE + [2.3.5,) From 25760062292179d50d54e1680a468048085ceadb Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Tue, 3 May 2022 13:42:18 +0200 Subject: [PATCH 15/20] Create FUNDING.yml --- .github/FUNDING.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..389da54e --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: osopromadze +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 78f036e325755dccbcbfb74c165687560616f519 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Tue, 3 May 2022 13:49:29 +0200 Subject: [PATCH 16/20] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2906f0fd..8d982888 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ [![Build Status](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API.svg?branch=development)](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=coma123_Spring-Boot-Blog-REST-API&metric=alert_status)](https://sonarcloud.io/dashboard?id=coma123_Spring-Boot-Blog-REST-API) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3706/badge)](https://bestpractices.coreinfrastructure.org/projects/3706) +Buy Me A Coffee + # Spring Boot, MySQL, Spring Security, JWT, JPA, Rest API Build Restful CRUD API for a blog using Spring Boot, Mysql, JPA and Hibernate. From 0c58cbaebcb517f18f6bc6b4bf8b134382e31d1e Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Tue, 3 May 2022 13:52:31 +0200 Subject: [PATCH 17/20] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d982888..12242911 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ [![Build Status](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API.svg?branch=development)](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=coma123_Spring-Boot-Blog-REST-API&metric=alert_status)](https://sonarcloud.io/dashboard?id=coma123_Spring-Boot-Blog-REST-API) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3706/badge)](https://bestpractices.coreinfrastructure.org/projects/3706) -Buy Me A Coffee +

+
+Buy Me A Coffee +

# Spring Boot, MySQL, Spring Security, JWT, JPA, Rest API From b21266df392e14965fd063e95a9db756cdcbdf4f Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Tue, 17 May 2022 20:14:08 +0200 Subject: [PATCH 18/20] Update README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 12242911..2906f0fd 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,5 @@ [![Build Status](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API.svg?branch=development)](https://travis-ci.com/coma123/Spring-Boot-Blog-REST-API) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=coma123_Spring-Boot-Blog-REST-API&metric=alert_status)](https://sonarcloud.io/dashboard?id=coma123_Spring-Boot-Blog-REST-API) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3706/badge)](https://bestpractices.coreinfrastructure.org/projects/3706) -

-
-Buy Me A Coffee -

- # Spring Boot, MySQL, Spring Security, JWT, JPA, Rest API Build Restful CRUD API for a blog using Spring Boot, Mysql, JPA and Hibernate. From d3d3e42d0c67cc96e37f31f1c28b804100f7ea22 Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Tue, 17 May 2022 20:16:43 +0200 Subject: [PATCH 19/20] Delete .travis.yml --- .travis.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 891a6c7f..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: java -dist: trusty -os: linux -addons: - sonarcloud: - organization: "coma123" - token: - secure: "fVilZ8rDtzqhxL7nEXCksKTnxdQXL2Ab5pSmpL0zZHw3zKsiKMWtuzMzIO11g+LIy6P+5sT+3ZAdcEwFeFM02R/CMpGmCIwHqNw7AvPeK8Vl6zeUEmAiV4yboIGL/7AksmSHx2nHZiQagUrLZKFhHaM3YpMmyhhbxuSxJNkZ95NPr43I5TfT7mqDWiaY/Hhmg29N8qjAO51j21j4eZwQLJIDlfnCUcGbTMHmlKsfJIuMcVPUQIE5w5rDaiMDyDdOZxlY/IKXi6JDGHP/TRthFk8zddqVj5qtzkCNKpl0K7ReMHdJb6aTSIsn6IVD+fHRev5ik2FF7HZ8DF0lC/0S62bVcmzTuF0WEWaWNre3l69dB0HBKY0GDxA4hskhVjRSMKjGKrH5Bx/LVXAo2a+U+uIO8ZmB4P7S4rwNF34ZnTke/yw7OmtesZWCDXZNzoidq59BRPL4RkkG0J1FMcWC47AsdnJC1JOX/bdunJ8Nmj2Lxil0RcLgDKK/L0La3UnNE8iKH8gE2E+rwHpKfF0wNt/mzpJYzXJ/l9DwRFyTsJoaVxDshIyM709Hp91CGy2JuNI7FeZZJK3laDmE4dHpr88MOvlPNHhvuxQG1MXUNNI1H2n1ZQlH8p9ZBgouG1LmRtY3GeyiuoSbQWmtUq4iAhb5F5G5/uHwS+BrLLNZSHo=" -script: - # the following command line builds the project, runs the tests with coverage and then execute the SonarCloud analysis - - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar -Dsonar.projectKey=coma123_Spring-Boot-Blog-REST-API - -before_install: - - chmod +x mvnw -cache: - directories: - - '$HOME/.m2/repository' - - '$HOME/.sonar/cache' From 29a2558f5dfe9d65cd4ac8f23184f27ce939d0aa Mon Sep 17 00:00:00 2001 From: Omari Sopromadze Date: Sat, 19 Aug 2023 23:01:02 +0200 Subject: [PATCH 20/20] ci: add sonarcloud (#58) --- .github/workflows/build.yml | 37 +++++++++++++++++++++++++++++++++++++ pom.xml | 2 ++ 2 files changed, 39 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..e943cfb1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,37 @@ +name: SonarCloud +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build and analyze + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: 'zulu' + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Maven packages + uses: actions/cache@v3 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=osopromadze_Spring-Boot-Blog-REST-API \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1a2dfb50..4b6fd187 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,8 @@ UTF-8 UTF-8 1.8 + coma123 + https://sonarcloud.io