From b271e18f1ecef819db740c2c6fd87b71fe95f798 Mon Sep 17 00:00:00 2001 From: Ahmed Muhammed Abdelaty Date: Wed, 30 Oct 2024 15:41:09 +0300 Subject: [PATCH 1/4] Project: Add Checkstyle for code style enforcement --- .github/workflows/checkstyle.yml | 21 ++++++++ build.gradle | 14 ++++++ config/checkstyle/checkstyle.xml | 85 ++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 .github/workflows/checkstyle.yml create mode 100644 config/checkstyle/checkstyle.xml diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml new file mode 100644 index 0000000..a266d9c --- /dev/null +++ b/.github/workflows/checkstyle.yml @@ -0,0 +1,21 @@ +name: Checkstyle + +on: [ pull_request ] + +jobs: + checkstyle: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'adopt' + - name: Run Checkstyle + run: ./gradlew checkstyleMain checkstyleTest + - name: Upload Checkstyle results + uses: actions/upload-artifact@v4 + with: + name: checkstyle-results + path: build/reports/checkstyle/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2bfdcbb..a9dc92d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,20 @@ plugins { id 'org.springframework.boot' version '3.3.4' id 'io.spring.dependency-management' version '1.1.6' id 'org.flywaydb.flyway' version "10.18.0" + id 'checkstyle' +} + +checkstyle { + toolVersion = "10.8.0" + configFile = file("config/checkstyle/checkstyle.xml") + maxWarnings = 0 +} + +tasks.withType(Checkstyle).configureEach { + reports { + xml.required = false + html.required = true + } } group = 'com.activecourses' diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000..5578116 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From c2efea5d7aa3bb2018b976e09a477783e7fe6ee2 Mon Sep 17 00:00:00 2001 From: Ahmed Muhammed Abdelaty Date: Wed, 30 Oct 2024 15:52:58 +0300 Subject: [PATCH 2/4] Project: Update Checkstyle --- .github/workflows/checkstyle.yml | 21 --------- .github/workflows/gradle.yml | 76 ++++++++++++++++---------------- build.gradle | 2 +- config/checkstyle/checkstyle.xml | 33 +++----------- 4 files changed, 44 insertions(+), 88 deletions(-) delete mode 100644 .github/workflows/checkstyle.yml diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml deleted file mode 100644 index a266d9c..0000000 --- a/.github/workflows/checkstyle.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Checkstyle - -on: [ pull_request ] - -jobs: - checkstyle: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 11 - uses: actions/setup-java@v4 - with: - java-version: '21' - distribution: 'adopt' - - name: Run Checkstyle - run: ./gradlew checkstyleMain checkstyleTest - - name: Upload Checkstyle results - uses: actions/upload-artifact@v4 - with: - name: checkstyle-results - path: build/reports/checkstyle/ \ No newline at end of file diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index ae9cea7..85bac23 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,6 +1,6 @@ name: Java CI with Gradle -on: [push, pull_request] +on: [ push, pull_request ] permissions: contents: read @@ -10,40 +10,40 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up JDK 21 - uses: actions/setup-java@v4 - with: - java-version: '21' - distribution: 'temurin' - cache: gradle - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew build -x test - - - name: Run tests - run: ./gradlew test - - - name: Publish Test Results - uses: actions/upload-artifact@v4 - if: always() - with: - name: test-results - path: | - build/reports/tests/test/ - build/test-results/test/ - - - name: Update status check - if: success() - run: echo "Tests passed" > status.txt || echo "Tests failed" > status.txt - - - name: Upload status check - uses: actions/upload-artifact@v4 - with: - name: status-check - path: status.txt + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run Checkstyle + run: ./gradlew checkstyleMain checkstyleTest + + - name: Build with Gradle + run: ./gradlew build -x test + + - name: Run tests + run: ./gradlew test + + - name: Publish Test Results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: | + build/reports/tests/test/ + build/test-results/test/ + + - name: Publish Checkstyle Results + uses: actions/upload-artifact@v4 + if: always() + with: + name: checkstyle-results + path: build/reports/checkstyle/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index a9dc92d..bc6b600 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { checkstyle { toolVersion = "10.8.0" configFile = file("config/checkstyle/checkstyle.xml") - maxWarnings = 0 + maxWarnings = 30 } tasks.withType(Checkstyle).configureEach { diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 5578116..3a4884e 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -15,15 +15,10 @@ - - - - - - - + + @@ -32,8 +27,9 @@ - - + + + @@ -41,18 +37,14 @@ - - - - @@ -61,25 +53,10 @@ - - - - - - - - - - - - - - - \ No newline at end of file From 892f34214611414e7898dcce8234c820aa83f683 Mon Sep 17 00:00:00 2001 From: Ahmed Muhammed Abdelaty Date: Wed, 30 Oct 2024 16:05:58 +0300 Subject: [PATCH 3/4] Project: Update Checkstyle --- build.gradle | 2 +- config/checkstyle/checkstyle.xml | 33 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index bc6b600..a9dc92d 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { checkstyle { toolVersion = "10.8.0" configFile = file("config/checkstyle/checkstyle.xml") - maxWarnings = 30 + maxWarnings = 0 } tasks.withType(Checkstyle).configureEach { diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 3a4884e..b1e57e0 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -13,22 +13,20 @@ + + + + + - - - - - - - - - - - - - - - + + + + + + + + @@ -37,9 +35,11 @@ + + @@ -52,8 +52,7 @@ - - + From 41a4aed5751fdad203e6087f86440f312360b33c Mon Sep 17 00:00:00 2001 From: Ahmed Muhammed Abdelaty Date: Wed, 30 Oct 2024 16:42:23 +0300 Subject: [PATCH 4/4] Fix: Resolve Checkstyle warnings --- .../upwork/UpworkApplication.java | 9 +++---- .../security/jwt/AuthEntryPointJwt.java | 4 +++- .../config/security/jwt/AuthTokenFilter.java | 6 ++++- .../config/security/jwt/JwtService.java | 6 ++++- .../controller/role/RoleController.java | 5 +++- .../controller/user/UserController.java | 16 +++++++++---- .../authentication/login/LoginRequestDto.java | 8 +++++-- .../upwork/model/RefreshToken.java | 10 ++++---- .../com/activecourses/upwork/model/User.java | 2 +- .../upwork/service/RefreshTokenService.java | 8 +++++-- .../authentication/AuthServiceImpl.java | 24 +++++++++++++------ 11 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/activecourses/upwork/UpworkApplication.java b/src/main/java/com/activecourses/upwork/UpworkApplication.java index 07b656c..e9ad16b 100644 --- a/src/main/java/com/activecourses/upwork/UpworkApplication.java +++ b/src/main/java/com/activecourses/upwork/UpworkApplication.java @@ -6,11 +6,8 @@ @SpringBootApplication @EnableJpaAuditing - public class UpworkApplication { - - public static void main(String[] args) { - SpringApplication.run(UpworkApplication.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(UpworkApplication.class, args); + } } diff --git a/src/main/java/com/activecourses/upwork/config/security/jwt/AuthEntryPointJwt.java b/src/main/java/com/activecourses/upwork/config/security/jwt/AuthEntryPointJwt.java index dcef155..5d8d1c3 100644 --- a/src/main/java/com/activecourses/upwork/config/security/jwt/AuthEntryPointJwt.java +++ b/src/main/java/com/activecourses/upwork/config/security/jwt/AuthEntryPointJwt.java @@ -24,7 +24,9 @@ public class AuthEntryPointJwt implements AuthenticationEntryPoint { private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class); @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { logger.error("Unauthorized error: {}", authException.getMessage()); diff --git a/src/main/java/com/activecourses/upwork/config/security/jwt/AuthTokenFilter.java b/src/main/java/com/activecourses/upwork/config/security/jwt/AuthTokenFilter.java index eb5b478..e13734d 100644 --- a/src/main/java/com/activecourses/upwork/config/security/jwt/AuthTokenFilter.java +++ b/src/main/java/com/activecourses/upwork/config/security/jwt/AuthTokenFilter.java @@ -28,7 +28,11 @@ public class AuthTokenFilter extends OncePerRequestFilter { private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class); @Override - protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { + protected void doFilterInternal(@NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain) + throws ServletException, IOException { + try { String jwt = jwtService.getJwtFromCookies(request); if (jwt != null && jwtService.validateJwtToken(jwt)) { diff --git a/src/main/java/com/activecourses/upwork/config/security/jwt/JwtService.java b/src/main/java/com/activecourses/upwork/config/security/jwt/JwtService.java index 8ad36ba..9153891 100644 --- a/src/main/java/com/activecourses/upwork/config/security/jwt/JwtService.java +++ b/src/main/java/com/activecourses/upwork/config/security/jwt/JwtService.java @@ -70,7 +70,11 @@ public ResponseCookie getCleanJwtCookie() { } public ResponseCookie getCleanJwtRefreshCookie() { - return ResponseCookie.from(jwtRefreshCookie, "").path("/api/auth/refresh-token").maxAge(0).httpOnly(true).build(); + return ResponseCookie.from(jwtRefreshCookie, "") + .path("/api/auth/refresh-token") + .maxAge(0) + .httpOnly(true) + .build(); } public String generateAccessToken(UserDetails userDetails) { diff --git a/src/main/java/com/activecourses/upwork/controller/role/RoleController.java b/src/main/java/com/activecourses/upwork/controller/role/RoleController.java index ba6f6d5..49c9b13 100644 --- a/src/main/java/com/activecourses/upwork/controller/role/RoleController.java +++ b/src/main/java/com/activecourses/upwork/controller/role/RoleController.java @@ -96,7 +96,10 @@ public ResponseEntity assignRolesToUser(@PathVariable int id, @Requ : buildResponseEntity(HttpStatus.NOT_FOUND, false, null, "User not found."); } - private ResponseEntity buildResponseEntity(HttpStatus status, boolean success, Object data, Object error) { + private ResponseEntity buildResponseEntity(HttpStatus status, + boolean success, + Object data, + Object error) { return ResponseEntity .status(status) .body(ResponseDto diff --git a/src/main/java/com/activecourses/upwork/controller/user/UserController.java b/src/main/java/com/activecourses/upwork/controller/user/UserController.java index f60767a..2ed9772 100644 --- a/src/main/java/com/activecourses/upwork/controller/user/UserController.java +++ b/src/main/java/com/activecourses/upwork/controller/user/UserController.java @@ -30,10 +30,18 @@ public class UserController { @Operation(summary = "Get all users", description = "Retrieve a paginated list of all users. Only accessible by users with the ROLE_ADMIN role.", parameters = { - @Parameter(name = "pageNo", in = ParameterIn.QUERY, description = "Page number", schema = @Schema(type = "integer", defaultValue = "0")), - @Parameter(name = "pageSize", in = ParameterIn.QUERY, description = "Page size", schema = @Schema(type = "integer", defaultValue = "10")), - @Parameter(name = "sortBy", in = ParameterIn.QUERY, description = "Sort by", schema = @Schema(type = "string", defaultValue = "id")), - @Parameter(name = "sortDir", in = ParameterIn.QUERY, description = "Sort direction", schema = @Schema(type = "string", defaultValue = "asc")) + @Parameter(name = "pageNo", in = ParameterIn.QUERY, + description = "Page number", + schema = @Schema(type = "integer", defaultValue = "0")), + @Parameter(name = "pageSize", in = ParameterIn.QUERY, + description = "Page size", + schema = @Schema(type = "integer", defaultValue = "10")), + @Parameter(name = "sortBy", in = ParameterIn.QUERY, + description = "Sort by", + schema = @Schema(type = "string", defaultValue = "id")), + @Parameter(name = "sortDir", in = ParameterIn.QUERY, + description = "Sort direction", + schema = @Schema(type = "string", defaultValue = "asc")) } ) @PreAuthorize("hasRole('ROLE_ADMIN')") diff --git a/src/main/java/com/activecourses/upwork/dto/authentication/login/LoginRequestDto.java b/src/main/java/com/activecourses/upwork/dto/authentication/login/LoginRequestDto.java index 98d33c7..914b610 100644 --- a/src/main/java/com/activecourses/upwork/dto/authentication/login/LoginRequestDto.java +++ b/src/main/java/com/activecourses/upwork/dto/authentication/login/LoginRequestDto.java @@ -20,8 +20,12 @@ public class LoginRequestDto { @Size(min = 6, message = "Password must be at least 6 characters long") private String password; - public LoginRequestDto(@Email(message = "Email is not valid") @NotEmpty(message = "Email is required") @NotNull(message = "Email is required") String email, - @NotEmpty(message = "Password is required") @NotNull(message = "Password is required") @Size(min = 6, message = "Password must be at least 6 characters long") String password) { + public LoginRequestDto(@Email(message = "Email is not valid") + @NotEmpty(message = "Email is required") + @NotNull(message = "Email is required") String email, + @NotEmpty(message = "Password is required") + @NotNull(message = "Password is required") + @Size(min = 6, message = "Password must be at least 6 characters long") String password) { this.email = email; this.password = password; } diff --git a/src/main/java/com/activecourses/upwork/model/RefreshToken.java b/src/main/java/com/activecourses/upwork/model/RefreshToken.java index 5590594..019cf4b 100644 --- a/src/main/java/com/activecourses/upwork/model/RefreshToken.java +++ b/src/main/java/com/activecourses/upwork/model/RefreshToken.java @@ -32,10 +32,10 @@ public class RefreshToken { @Override public String toString() { - return "RefreshToken{" + - "id=" + id + - ", token='" + token + '\'' + - ", expiryDate=" + expiryDate + - '}'; + return "RefreshToken{" + + "id=" + id + + ", token='" + token + '\'' + + ", expiryDate=" + expiryDate + + '}'; } } \ No newline at end of file diff --git a/src/main/java/com/activecourses/upwork/model/User.java b/src/main/java/com/activecourses/upwork/model/User.java index 7b310db..6bd8aed 100644 --- a/src/main/java/com/activecourses/upwork/model/User.java +++ b/src/main/java/com/activecourses/upwork/model/User.java @@ -66,7 +66,7 @@ public class User implements UserDetails, Principal { @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, optional = true) private RefreshToken refreshToken; - @OneToOne(mappedBy = "user",cascade = CascadeType.ALL) + @OneToOne(mappedBy = "user", cascade = CascadeType.ALL) private UserProfile userProfile; @ManyToMany(fetch = FetchType.EAGER) @JoinTable( diff --git a/src/main/java/com/activecourses/upwork/service/RefreshTokenService.java b/src/main/java/com/activecourses/upwork/service/RefreshTokenService.java index 9fe742d..da1512b 100644 --- a/src/main/java/com/activecourses/upwork/service/RefreshTokenService.java +++ b/src/main/java/com/activecourses/upwork/service/RefreshTokenService.java @@ -35,7 +35,9 @@ public class RefreshTokenService { private final UserRepository userRepository; private final JwtService jwtService; - public RefreshTokenService(RefreshTokenRepository refreshTokenRepository, UserRepository userRepository, JwtService jwtService) { + public RefreshTokenService(RefreshTokenRepository refreshTokenRepository, + UserRepository userRepository, + JwtService jwtService) { this.refreshTokenRepository = refreshTokenRepository; this.userRepository = userRepository; this.jwtService = jwtService; @@ -119,7 +121,9 @@ public RefreshToken createRefreshToken(int userId) { public void verifyExpiration(RefreshToken token) { if (token.getExpiryDate().compareTo(Instant.now()) < 0) { refreshTokenRepository.delete(token); - throw new TokenRefreshException(token.getToken(), "Refresh token was expired. Please sign in again to obtain a new refresh token."); + throw new TokenRefreshException(token.getToken(), + "Refresh token was expired. " + + "Please sign in again to obtain a new refresh token."); } } diff --git a/src/main/java/com/activecourses/upwork/service/authentication/AuthServiceImpl.java b/src/main/java/com/activecourses/upwork/service/authentication/AuthServiceImpl.java index 45207a0..9441ffa 100644 --- a/src/main/java/com/activecourses/upwork/service/authentication/AuthServiceImpl.java +++ b/src/main/java/com/activecourses/upwork/service/authentication/AuthServiceImpl.java @@ -92,11 +92,15 @@ public ResponseDto login(LoginRequestDto loginRequestDto) { } Authentication authentication = authenticationManager - .authenticate(new UsernamePasswordAuthenticationToken(loginRequestDto.getEmail(), loginRequestDto.getPassword())); + .authenticate(new UsernamePasswordAuthenticationToken( + loginRequestDto.getEmail(), + loginRequestDto.getPassword() + )); SecurityContextHolder.getContext().setAuthentication(authentication); - UserDetails userDetails = customUserDetailsService.loadUserByUsername(loginRequestDto.getEmail()); + UserDetails userDetails = customUserDetailsService + .loadUserByUsername(loginRequestDto.getEmail()); ResponseCookie jwtCookie = jwtService.generateJwtCookie(userDetails); @@ -104,7 +108,8 @@ public ResponseDto login(LoginRequestDto loginRequestDto) { RefreshToken refreshToken = refreshTokenService.createRefreshToken(userId); - ResponseCookie refreshJwtCookie = jwtService.generateRefreshJwtCookie(refreshToken.getToken()); + ResponseCookie refreshJwtCookie = jwtService + .generateRefreshJwtCookie(refreshToken.getToken()); return ResponseDto .builder() @@ -117,7 +122,8 @@ public ResponseDto login(LoginRequestDto loginRequestDto) { @Override public ResponseEntity logout() { logger.info("User logout attempt"); - Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Object principal = SecurityContextHolder.getContext() + .getAuthentication().getPrincipal(); if (!principal.toString().equals("anonymousUser")) { int userId = ((User) principal).getId(); refreshTokenService.deleteByUserId(userId); @@ -166,7 +172,8 @@ public User findByEmail(String email) { @Override public void sendVerificationEmail(User user) { logger.info("Sending verification email to: {}", user.getEmail()); - String verificationLink = "http://localhost:8080/api/users/verify?token=" + user.getVerificationToken(); + String verificationLink = "http://localhost:8080/api/users/verify?token=" + + user.getVerificationToken(); SimpleMailMessage message = new SimpleMailMessage(); message.setTo(user.getEmail()); @@ -196,7 +203,10 @@ public boolean reactivateUser(int userId) { } static User unwrapUser(Optional entity) { - if (entity.isPresent()) return entity.get(); - else throw new UnsupportedOperationException("Unimplemented method 'unwrapUser'"); + if (entity.isPresent()) { + return entity.get(); + } else { + throw new UnsupportedOperationException("Unimplemented method 'unwrapUser'"); + } } }