diff --git a/pom.xml b/pom.xml index 07434795..1b55d803 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,14 @@ hibernate-validator + + com.google.code.gson + gson + 2.10.1 + + + + diff --git a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java index 27887e26..c3c54d99 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java +++ b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java @@ -5,8 +5,10 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.UserEntity; - +import net.gepafin.tendermanagement.util.Utils; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.time.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,11 +20,17 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; +import com.google.gson.Gson; + +import static io.micrometer.common.util.StringUtils.isEmpty; + + @Component public class TokenProvider { private final Logger log = LoggerFactory.getLogger(TokenProvider.class); @@ -35,13 +43,19 @@ public class TokenProvider { private SecretKey key; + private static final String AUTHORITIES_KEY = "auth"; + private static final String MERCHANTID="merchantId"; + + public static final String INVALID_USER = "invalid_user"; + static final String AUTH_SECRET = "X-Api-Secret"; + @PostConstruct public void init() { this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); log.info("JWT Secret Key initialized."); } - public String createToken(Authentication authentication, Boolean rememberMe, UserEntity user) { + public String createToken(Authentication authentication, Boolean rememberMe, UserEntity user) { String authorities = authentication.getAuthorities().stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); @@ -60,7 +74,7 @@ public class TokenProvider { String payload = authentication.getName(); if(user != null) { - payload += ":"+user.getId(); + payload += ":"+user.getId(); } String token = Jwts.builder() @@ -110,4 +124,76 @@ public class TokenProvider { return false; } } + public Map getUserInfoAndUserIdFromToken(HttpServletRequest request) { + Map userInfo = new HashMap<>(); + String authSecretHeader=request.getHeader(AUTH_SECRET); +// userInfo.put(MERCHANTID, null); + String bearerToken = request.getHeader("Authorization"); + String token = ""; + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { + token = bearerToken.substring(7, bearerToken.length()); + } + extractDetailsFromTheToken(userInfo, authSecretHeader, token); + return userInfo; + } + public Map extractDetailsFromTheToken(Map userInfo, String authSecretHeader, + String token) { + String payload = null; + Boolean isSuperAdmin = false; +// if (StringUtils.hasText(token) && token.endsWith("_superKey" + getSuperUserToken())) { +// Map payloadMap = getUserDetailsForSuperUser(token); +// payload = payloadMap.get("sub").toString(); +// isSuperAdmin = true; +// +// } else + if (!isEmpty(authSecretHeader)) { + String secret = Utils.decodeBase64String(authSecretHeader); + String[] tokenArr = secret.split("\\.", 2); + String[] merchant = tokenArr[0].split("-"); + if (ArrayUtils.isNotEmpty(merchant) && 2 <= merchant.length) { + userInfo.put(MERCHANTID, merchant[1]); + return userInfo; + } + + } else { + payload = getUserDetails(token); + } + if (payload != null && !isSuperAdmin) { + String[] payloadString = payload.split(":");{ + + if (payloadString.length > 1) { +// userInfo.put(MERCHANTID, payloadString[1]); +// userInfo.put("associatedTags", payloadString[2]); + userInfo.put("userId", payloadString[1]); + } + } + + if (payloadString.length > 1) { +// userInfo.put(MERCHANTID, payloadString[1]); +// userInfo.put("associatedTags", payloadString[2]); + userInfo.put("userId", payloadString[1]); + } + } else { + String[] payloadString = payload.split(":"); + + if (payloadString.length > 1) { + userInfo.put("userId", payloadString[1]); + } + } + + return userInfo; + } + public Map getUserDetailsForSuperUser(String token) { + Base64.Decoder decoder = Base64.getUrlDecoder(); + String[] parts = token.split("\\."); // Splitting header, payload and signature + Gson g = new Gson(); + return g.fromJson(new String(decoder.decode(parts[1])), Map.class); + } +// public String getSuperUserToken() { +// return superUserToken; +// } + public String getUserDetails(String token) { + Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody(); + return claims.getSubject(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index fc2b966c..d034f8a7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -14,7 +14,6 @@ import net.gepafin.tendermanagement.enums.CallTypeEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; -import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -48,14 +47,17 @@ public class CallDao { @Autowired private CallTargetAudienceChecklistRepository callTargetAudienceChecklistRepository; - public CreateCallResponseBean createCall(CreateCallRequest createCallRequest) { + @Autowired + private UserRepository userRepository; + + public CreateCallResponseBean createCall(CreateCallRequest createCallRequest, Long userId) { try { CreateCallResponseBean createCallResponseBean=null; CallEntity callEntity = convertToCallEntity(createCallRequest); List evaluationCriteriaEntities = convertToEvaluationCriteriaEntities(createCallRequest.getCriteria(), callEntity); List documentEntities = convertToDocumentEntities(createCallRequest.getDocs(), callEntity); List imageEntities=convertToDocumentEntities(createCallRequest.getImages(),callEntity); - List faqEntities = convertToFaqEntities(createCallRequest.getFaq(), callEntity); + List faqEntities = convertToFaqEntities(createCallRequest.getFaq(), callEntity, userId); List amiedTo=convertLookUpDataEntities(createCallRequest.getAimedTo(),callEntity,LookUpDataTypeEnum.AIMED_TO); List checkList=convertLookUpDataEntities(createCallRequest.getAimedTo(),callEntity,LookUpDataTypeEnum.CHECKLIST); createCallResponseBean= assembleCreateCallResponseBean(callEntity, evaluationCriteriaEntities, documentEntities, faqEntities,imageEntities); @@ -125,18 +127,18 @@ public class CallDao { } - public List convertToFaqEntities(List faqReqList, CallEntity callEntity) { - List faqEntities = faqReqList.stream().map(req -> convertToFaqEntity(req, callEntity)).collect(Collectors.toList()); + public List convertToFaqEntities(List faqReqList, CallEntity callEntity, Long userId) { + List faqEntities = faqReqList.stream().map(req -> convertToFaqEntity(req, callEntity, userId)).collect(Collectors.toList()); faqRepository.saveAll(faqEntities); return faqEntities; } - private FaqEntity convertToFaqEntity(FaqReq faqReq, CallEntity callEntity) { + private FaqEntity convertToFaqEntity(FaqReq faqReq, CallEntity callEntity, Long userId) { FaqEntity faqEntity = new FaqEntity(); validateFaqEntity(faqReq.getQuestion()); -// UserEntity userEntity= userRepository.findById(1l) -// .orElseThrow(() -> new ResourceNotFoundException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.LOOK_UP_DATA_NOT_VALID_MSG))); -// faqEntity.setUser(userEntity); + UserEntity userEntity= userRepository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.LOOK_UP_DATA_NOT_VALID_MSG))); + faqEntity.setUser(userEntity); faqEntity.setIsVisible(true); if(faqReq.getIsVisible()!=null){ faqEntity.setIsVisible(faqReq.getIsVisible()); diff --git a/src/main/java/net/gepafin/tendermanagement/service/CallService.java b/src/main/java/net/gepafin/tendermanagement/service/CallService.java index 5f688af3..40dfd65f 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CallService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CallService.java @@ -1,10 +1,11 @@ package net.gepafin.tendermanagement.service; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.model.request.CreateCallRequest; import net.gepafin.tendermanagement.model.response.CreateCallResponseBean; public interface CallService { - CreateCallResponseBean createCall(CreateCallRequest createCallRequest); + CreateCallResponseBean createCall(HttpServletRequest request, CreateCallRequest createCallRequest); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java index 7e59aff6..cb4b76bc 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java @@ -1,5 +1,7 @@ package net.gepafin.tendermanagement.service.impl; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.dao.CallDao; import net.gepafin.tendermanagement.model.request.CreateCallRequest; import net.gepafin.tendermanagement.model.response.CreateCallResponseBean; @@ -7,6 +9,8 @@ import net.gepafin.tendermanagement.service.CallService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Map; + @Service public class CallServiceImpl implements CallService { @@ -14,8 +18,12 @@ public class CallServiceImpl implements CallService { @Autowired private CallDao callDao; + @Autowired + private TokenProvider tokenProvider; + @Override - public CreateCallResponseBean createCall(CreateCallRequest createCallRequest) { - return callDao.createCall(createCallRequest); + public CreateCallResponseBean createCall(HttpServletRequest request, CreateCallRequest createCallRequest) { + Map userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); + return callDao.createCall(createCallRequest, Long.parseLong(userInfo.get("userId").toString())); } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index ee81849b..21392d61 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -3,9 +3,12 @@ package net.gepafin.tendermanagement.util; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import io.micrometer.common.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.List; import java.util.stream.Collectors; @@ -58,5 +61,12 @@ public class Utils { return filePath; } } + public static String decodeBase64String(String decodedString) { + if (StringUtils.isBlank(decodedString)) { + return decodedString; + } + byte[] decode = Base64.getDecoder().decode(decodedString.getBytes(StandardCharsets.UTF_8)); + return new String(decode, StandardCharsets.UTF_8); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java index a6c9bfc0..bd8863b5 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CallApi.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import net.gepafin.tendermanagement.model.request.CreateCallRequest; import net.gepafin.tendermanagement.model.response.CreateCallResponseBean; @@ -29,7 +30,7 @@ public interface CallApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> createCall( + public ResponseEntity> createCall(HttpServletRequest request, @Parameter(description = "Call request object", required = true) @Valid @RequestBody CreateCallRequest createCallRequest); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index 5e68ecbd..d4165383 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.web.rest.api.impl; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.model.request.CreateCallRequest; @@ -26,8 +27,8 @@ public class CallApiController implements CallApi { @Override @Transactional(rollbackFor=Exception.class) - public ResponseEntity> createCall(CreateCallRequest createCallRequest) { - CreateCallResponseBean createCallResponseBean = callService.createCall(createCallRequest); + public ResponseEntity> createCall(HttpServletRequest request, CreateCallRequest createCallRequest) { + CreateCallResponseBean createCallResponseBean = callService.createCall(request, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_CREATED_SUCCESSFULLY_MSG))); } diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index bb80c810..eb0d2fdc 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -212,7 +212,7 @@ - +