Skip to content

Commit

Permalink
using tenant id when user is not authenticated
Browse files Browse the repository at this point in the history
  • Loading branch information
harmlessprince committed Feb 2, 2025
1 parent 12d2420 commit 201fa54
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 28 deletions.
18 changes: 9 additions & 9 deletions src/main/java/com/harmlessprince/ecommerceApi/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.harmlessprince.ecommerceApi.custom.AllowedKey;
import com.harmlessprince.ecommerceApi.exceptions.CustomBadRequestException;
import com.harmlessprince.ecommerceApi.user.User;
import com.harmlessprince.ecommerceApi.user.UserService;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
Expand Down Expand Up @@ -76,19 +77,18 @@ public static Sort.Direction getSortDirectionFiled(String input) {

public static Query getTenantAwareQuery() {
Query query = new Query();

User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (user != null && TenantContext.getCurrentTenant() != null) {
query.addCriteria(Criteria.where("tenant_id").is(TenantContext.getCurrentTenant()));
}
return query;
return getTenantAwareQuery(query);
}
public static Query getTenantAwareQuery(Criteria criteria) {
Query query = new Query(criteria);
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (user != null && TenantContext.getCurrentTenant() != null) {
query.addCriteria(Criteria.where("tenantId").is(TenantContext.getCurrentTenantID()));
return getTenantAwareQuery(query);
}

public static Query getTenantAwareQuery(Query query) {
if (TenantContext.getCurrentTenant() == null) {
throw new CustomBadRequestException("Tenant not set");
}
query.addCriteria(Criteria.where("tenantId").is(TenantContext.getCurrentTenantID()));
return query;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.harmlessprince.ecommerceApi.configs;

import com.harmlessprince.ecommerceApi.jwt.JwtService;
import com.harmlessprince.ecommerceApi.tenant.TenantService;
import com.harmlessprince.ecommerceApi.user.User;
import com.harmlessprince.ecommerceApi.user.UserService;
import com.harmlessprince.ecommerceApi.custom.AppConstants;
Expand Down Expand Up @@ -33,13 +34,15 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
private final UserService userService;
private final TenantService tenantService;


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


Expand All @@ -66,11 +69,9 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull Ht
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null && userId != null) {
User userDetails = userService.findById(userId);

request.setAttribute(AppConstants.CURRENT_USER_TENANT_ID, tenantId);
request.setAttribute(AppConstants.CURRENT_USER_TENANT_CODE, tenantCode);
request.setAttribute(AppConstants.CURRENT_USER_ROLE_NAME, role);

Collection<? extends GrantedAuthority> userAuthorities = userService.getAuthorities(userDetails.getRole());
if (jwtService.isTokenValid(token, userDetails)) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userAuthorities);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class AppConstants {

//PREFIX
public static final String TENANT_PREFIX = "tao_commerce_tenant_:";
public static final String TENANT_ID_PREFIX = "tao_commerce_tenant_id:";


//Session
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,22 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
}
String currentUserRole = (String) request.getAttribute(AppConstants.CURRENT_USER_ROLE_NAME);

String finalTenantId = tenantResolver.resolveTenantIdentifier(request);
String tenantCode = tenantResolver.resolveTenantIdentifier(request);

if (!StringUtils.hasText(finalTenantId) && !Objects.equals(currentUserRole, AppConstants.SUPER_ADMIN)) {
if (!StringUtils.hasText(tenantCode) && !Objects.equals(currentUserRole, AppConstants.SUPER_ADMIN)) {
throw new CustomBadRequestException("Tenant ID is missing from headers");
}

tenantService.validateTenantId(finalTenantId);
TenantContext.setCurrentTenant(finalTenantId);
TenantContext.setCurrentTenantId(request.getAttribute(AppConstants.CURRENT_USER_TENANT_ID).toString());
MDC.put("tenantId", finalTenantId);
tenantService.validateTenantId(tenantCode);
TenantContext.setCurrentTenant(tenantCode);
Object currentTenantId = request.getAttribute(AppConstants.CURRENT_USER_TENANT_ID);
if (currentTenantId != null) {
TenantContext.setCurrentTenantId(currentTenantId.toString());
}else{
String tenantId = tenantService.getTenantIdByCode(tenantCode);
TenantContext.setCurrentTenantId(tenantId);
}
MDC.put("tenantId", tenantCode);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.harmlessprince.ecommerceApi.product;

import com.harmlessprince.ecommerceApi.Utils;
import com.harmlessprince.ecommerceApi.review.RatingAggregationResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -20,8 +21,8 @@ public class CustomProductRepositoryImpl implements CustomProductRepository {

@Override
public List<Product> findSimilarProductsByCategory(String category, int limit) {
Query query = new Query();
query.addCriteria(Criteria.where("category").is(category));
Criteria criteria = Criteria.where("category").is(category);
Query query = Utils.getTenantAwareQuery(criteria);
query.limit(limit);
return mongoTemplate.find(query, Product.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public ResponseEntity<CustomSuccessResponse<ProductResponse>> updateProduct(
public ResponseEntity<CustomSuccessResponse<ProductResponse>> showProduct(
@PathVariable String productId
) {
Product product = productService.findById(productId);
Product product = productService.findByIdAndTenantId(productId, TenantContext.getCurrentTenantID());
return ResponseEntity.ok(new CustomSuccessResponse<>(productMapper.fromEntity(product), "Product retrieved"));
}

Expand All @@ -125,7 +125,7 @@ public ResponseEntity<CustomSuccessResponse<List<ProductResponse>>> getSimilarPr
@PathVariable String productId,
@RequestParam(defaultValue = "4") int limit
) {
Product product = productService.findById(productId);
Product product = productService.findByIdAndTenantId(productId, TenantContext.getCurrentTenantID());
List<Product> products = productService.findAllSimilarProducts(product, limit);
List<ProductResponse> productResponse = productMapper.fromEntityList(products);
return ResponseEntity.ok(new CustomSuccessResponse<>(productResponse, "Product retrieved"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ public interface ProductRepository extends MongoRepository<Product, String>, Cus
Optional<Product> findFirstByNameAndTenantId(String slug, String tenantId);
Boolean existsBySlugAndBrand(String name, String brand);

Optional<Product> findFirstByIdAndTenantId(String id, String tenantId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public Product findById(String id) {
return productRepository.findById(id).orElseThrow(() -> new CustomResourceNotFoundException("Product not found"));
}

public Product findByIdAndTenantId(String id, String tenantId) {
return productRepository.findFirstByIdAndTenantId(id, tenantId).orElseThrow(() -> new CustomResourceNotFoundException("Product not found"));
}

public Product findByName(String name) {
return productRepository.findByName(name).orElseThrow(() -> new CustomResourceNotFoundException("Product not found"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,25 @@ public Optional<Tenant> findByUser(User user) {

public void validateTenantId(String value) {
String key = AppConstants.TENANT_PREFIX + value;
String tenantId = valueOperations.get(key);
String tenantCode = valueOperations.get(key);
log.debug("Tenant id is {}", value);
if (!StringUtils.hasText(tenantId)) {
if (!StringUtils.hasText(tenantCode)) {
this.tenantRepository.findFirstByCode(value).orElseThrow(() -> new CustomBadRequestException("Invalid tenant id"));
valueOperations.set(key, value, 12, TimeUnit.HOURS);
}
}

public String getTenantIdByCode(String code) {
String key = AppConstants.TENANT_ID_PREFIX + code;
String tenantId = valueOperations.get(key);
if (!StringUtils.hasText(tenantId)) {
Tenant tenant = this.tenantRepository.findFirstByCode(code).orElseThrow(() -> new CustomBadRequestException("Invalid tenant id"));
tenantId = tenant.getId();
valueOperations.set(key, tenant.getId(), 12, TimeUnit.HOURS);
}
return tenantId;
}


public String generateTenantId(String name) {
// Normalize name to remove special characters and convert to lowercase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.harmlessprince.ecommerceApi.permission.Permission;
import com.harmlessprince.ecommerceApi.role.Role;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
Expand All @@ -16,6 +17,7 @@
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class UserService {
Expand Down Expand Up @@ -47,18 +49,20 @@ public User findById(String id) {

public static User getAuthenticatedUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return (User) authentication.getPrincipal();
if (authentication.getPrincipal() instanceof User) {
return (User) authentication.getPrincipal();
}
return null;
}

public Collection<? extends GrantedAuthority> getAuthorities(Role role) {
Set<GrantedAuthority> authorities = new HashSet<>();
// Query to fetch the role along with its permissions
Query roleQuery = new Query();
if(role == null) {
if (role == null) {
return authorities;
}
roleQuery.addCriteria(Criteria.where("id").is(role.getId()));

// Assuming Role has a field "permissions" (embedded or referenced)
Role fetchedRole = mongoTemplate.findOne(roleQuery, Role.class);
if (fetchedRole == null) {
Expand All @@ -68,7 +72,6 @@ public Collection<? extends GrantedAuthority> getAuthorities(Role role) {
String userRole = fetchedRole.getSlug();



// Construct the authorities

authorities.add(new SimpleGrantedAuthority(userRole));
Expand Down

0 comments on commit 201fa54

Please sign in to comment.