Skip to content

Commit

Permalink
added search filter
Browse files Browse the repository at this point in the history
  • Loading branch information
harmlessprince committed Jan 26, 2025
1 parent b9da13d commit 3c399f6
Show file tree
Hide file tree
Showing 24 changed files with 403 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.harmlessprince.ecommerceApi.auth;

import com.harmlessprince.ecommerceApi.role.Role;
import com.harmlessprince.ecommerceApi.role.RoleRepository;
import com.harmlessprince.ecommerceApi.user.User;
import com.harmlessprince.ecommerceApi.user.UserRepository;
import lombok.AllArgsConstructor;
Expand All @@ -10,18 +12,25 @@
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@AllArgsConstructor
public class AuthenticationService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final AuthenticationManager authenticationManager;
private final UserMapper userMapper;
private final RoleRepository roleRepository;

public User signup(RegisterUserRequest request) {
User user = userMapper.fromUseRequest(request);
user.setEmail(user.getEmail().toLowerCase());
user.setPassword(passwordEncoder.encode(user.getPassword()));
Optional<Role> role = roleRepository.findFirstBySlug("customer");
if(role.isPresent()) {
user.setRole(role.get());
}
return userRepository.save(user);
}

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/harmlessprince/ecommerceApi/auth/UserMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.harmlessprince.ecommerceApi.user.User;
import com.harmlessprince.ecommerceApi.user.UserResponse;
import com.harmlessprince.ecommerceApi.user.UserResponseWithRole;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -18,4 +19,15 @@ public User fromUseRequest(RegisterUserRequest request) {
public UserResponse fromUser(User user) {
return new UserResponse(user.getId(), user.getEmail(), user.getFullName(), user.getPhoneNumber(), user.getAddress());
}

public UserResponseWithRole fromUserWithRole(User user) {
UserResponseWithRole userResponse = new UserResponseWithRole();
userResponse.setRole(user.getRole());
userResponse.setId(user.getId());
userResponse.setEmail(user.getEmail());
userResponse.setFullName(user.getFullName());
userResponse.setPhoneNumber(user.getPhoneNumber());
userResponse.setAddress(user.getAddress());
return userResponse;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.harmlessprince.ecommerceApi.configs;

import com.harmlessprince.ecommerceApi.jwt.JwtService;
import com.harmlessprince.ecommerceApi.user.User;
import com.harmlessprince.ecommerceApi.user.UserService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
Expand All @@ -9,6 +11,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
Expand All @@ -18,18 +21,22 @@
import org.springframework.web.servlet.HandlerExceptionResolver;

import java.io.IOException;
import java.util.Collection;

//https://github.com/jwtk/jjwt?tab=readme-ov-file#creating-a-jwt
@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final HandlerExceptionResolver handlerExceptionResolver;
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
private final UserService userService;

JwtAuthenticationFilter(HandlerExceptionResolver handlerExceptionResolver, JwtService jwtService, UserDetailsService userDetailsService) {
JwtAuthenticationFilter(HandlerExceptionResolver handlerExceptionResolver, JwtService jwtService, UserDetailsService userDetailsService, UserService userService) {
this.handlerExceptionResolver = handlerExceptionResolver;
this.jwtService = jwtService;
this.userDetailsService = userDetailsService;
this.userService = userService;
}


Expand All @@ -50,9 +57,10 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull H

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null && email != null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(email);
User userDetails = (User) userDetailsService.loadUserByUsername(email);
Collection<? extends GrantedAuthority> userAuthorities = userService.getAuthorities(userDetails.getRole());
if (jwtService.isTokenValid(token, userDetails)) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userAuthorities);
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
Expand All @@ -21,6 +23,10 @@

@Configuration
@EnableWebSecurity
@EnableTransactionManagement
@EnableMethodSecurity(
securedEnabled = true
)
@Slf4j
public class SecurityConfiguration {
private final AuthenticationProvider authenticationProvider;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.harmlessprince.ecommerceApi.jwt;

import com.harmlessprince.ecommerceApi.user.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
Expand Down Expand Up @@ -35,7 +36,7 @@ public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}

public boolean isTokenValid(String token, UserDetails userDetails) {
public boolean isTokenValid(String token, User userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);
}
Expand All @@ -44,7 +45,7 @@ private boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}

public String generateToken(UserDetails userDetails) {
public String generateToken(User userDetails) {
return generateToken(new HashMap<>(), userDetails);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.harmlessprince.ecommerceApi.permission;

import com.harmlessprince.ecommerceApi.bases.BaseEntity;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Set;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Document(collection = "permissions")
public class Permission extends BaseEntity {
@Id
private String id;

@Indexed(unique = true)
private String name;

private Boolean status = true;

@Indexed(unique = true)
private String slug;

public void setSlug(String slug) {
this.slug = slug.replace(" ", "_").toLowerCase();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.harmlessprince.ecommerceApi.permission;

public class PermissionController {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.harmlessprince.ecommerceApi.permission;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface PermissionRepository extends MongoRepository<Permission, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.harmlessprince.ecommerceApi.permission;

public class PermissionService {
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
Expand Down Expand Up @@ -60,6 +61,7 @@ public ResponseEntity<CustomSuccessResponse<Map<String, Object>>> allProduct(
}

@PostMapping
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<Object>> createProduct(@RequestBody @Valid ProductRequest productRequest) {


Expand All @@ -84,6 +86,7 @@ public ResponseEntity<CustomSuccessResponse<Object>> createProduct(@RequestBody
}

@PatchMapping("/{productId}")
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<ProductResponse>> updateProduct(
@RequestBody @Valid UpdateProductRequest request,
@PathVariable String productId
Expand Down Expand Up @@ -114,6 +117,7 @@ public ResponseEntity<CustomSuccessResponse<List<ProductResponse>>> getSimilarPr
}

@DeleteMapping("/{productId}")
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<Object>> deleteProduct(
@PathVariable String productId
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;
Expand All @@ -21,6 +22,7 @@ public class ProductVariationController {
private final ProductMapper productMapper;

@PatchMapping("/{variationId}")
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<ProductResponse>> updateProductVariation(
@RequestBody @Valid UpdateProductVariation request,
@PathVariable String variationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;
Expand All @@ -21,6 +22,7 @@ public class ProductVariationPriceDetailController {


@PatchMapping("/{variationPriceDetailId}")
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<ProductResponse>> updateProductVariationPriceDetail(
@RequestBody @Valid ProductVariationPriceDetailRequest request,
@PathVariable String variationPriceDetailId
Expand All @@ -39,6 +41,7 @@ public ResponseEntity<CustomSuccessResponse<ProductResponse>> updateProductVaria
}

@PostMapping()
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<ProductResponse>> updateProductVariationPriceDetail(
@RequestBody @Valid ProductVariationPriceDetailRequest request
) {
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/com/harmlessprince/ecommerceApi/role/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.harmlessprince.ecommerceApi.role;

import com.harmlessprince.ecommerceApi.bases.BaseEntity;
import com.harmlessprince.ecommerceApi.permission.Permission;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Set;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Document(collection = "roles")
public class Role extends BaseEntity {

@Id
private String id;

@Indexed(unique = true)
private String name;

private Boolean status = true;

@Indexed(unique = true)
private String slug;

@DBRef
private Set<Permission> permissions;

public void setSlug() {
this.slug = this.name.replace(" ", "_").toLowerCase();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.harmlessprince.ecommerceApi.role;

import com.harmlessprince.ecommerceApi.handler.CustomSuccessResponse;
import com.harmlessprince.ecommerceApi.paymentMethod.PaymentMethod;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/v1/roles")
@AllArgsConstructor
public class RoleController {
private final RoleService roleService;

@GetMapping
@PreAuthorize("hasAnyAuthority('admin', 'superadmin')")
public ResponseEntity<CustomSuccessResponse<List<Role>>> findAll() {
List<Role> roles = roleService.getAllRoles();
return ResponseEntity.ok(new CustomSuccessResponse<>(roles));
}

// @GetMapping("/{userId}")
// @PreAuthorize("hasAuthority('admin')")
// public ResponseEntity<CustomSuccessResponse<?>> assignRoleToUser() {
// List<Role> roles = roleService.getAllRoles();
// return ResponseEntity.ok(new CustomSuccessResponse<>(roles));
// }


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.harmlessprince.ecommerceApi.role;

import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.Optional;

public interface RoleRepository extends MongoRepository<Role, String> {
Optional<Role> findFirstBySlug(String slug);
}
Loading

0 comments on commit 3c399f6

Please sign in to comment.