Subversion Repositories SmartDukaan

Rev

Rev 35272 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service.authentication;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator.Builder;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.spice.profitmandi.common.ResponseCodeHolder;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.UserInfo;
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
import com.spice.profitmandi.dao.repository.fofo.PartnerTypeChangeService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.time.Instant;
import java.util.*;

@Component
public class JWTUtil {
    private static final String SECRET_KEY = "newsecretkey";
    private static final String USER_ID = "userId";
    private static final String EMAIL = "email";
    private static final String PROFIT_MANDI = "profitmandi";
    //60 days
    private static final int EXPIRE_TIME_IN_SECONDS = ((60 * 60) * 24) * 60;
    private static Algorithm ALGORITHM;
    private static final Logger LOGGER = LogManager.getLogger(JWTUtil.class);


    @Autowired
    PartnerTypeChangeService partnerTypeChangeService;

    static {
        try {
            ALGORITHM = Algorithm.HMAC256(SECRET_KEY);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String create(int userId, int retailerId, String[] roleIds) {
        try {
            return createBuilder()
                    .withClaim(ProfitMandiConstants.USER_ID, userId)
                    .withClaim(ProfitMandiConstants.RETAILER_ID, retailerId)
                    .withArrayClaim(ProfitMandiConstants.ROLE_IDS, roleIds)
                    .sign(ALGORITHM);
        } catch (JWTCreationException jwtCreationException) {
            throw new RuntimeException(ResponseCodeHolder.getMessage("USR_1011"));
        }
    }

    public String create(String email, int userId, int retailerId, String[] roleIds) {
        try {
            return createBuilder()
                    .withClaim(ProfitMandiConstants.EMAIL_ID, email)
                    .withClaim(ProfitMandiConstants.USER_ID, userId)
                    .withClaim(ProfitMandiConstants.RETAILER_ID, retailerId)
                    .withArrayClaim(ProfitMandiConstants.ROLE_IDS, roleIds)
                    .sign(ALGORITHM);
        } catch (JWTCreationException jwtCreationException) {
            throw new RuntimeException(ResponseCodeHolder.getMessage("USR_1011"));
        }
    }

    public String createImpersonationToken(String targetEmail, int targetUserId, int targetRetailerId,
                                            String[] targetRoleIds, int authUserId, String authUserEmail) {
        try {
            return createBuilder()
                    .withClaim(ProfitMandiConstants.EMAIL_ID, targetEmail)
                    .withClaim(ProfitMandiConstants.USER_ID, targetUserId)
                    .withClaim(ProfitMandiConstants.RETAILER_ID, targetRetailerId)
                    .withArrayClaim(ProfitMandiConstants.ROLE_IDS, targetRoleIds)
                    .withClaim(ProfitMandiConstants.AUTH_USER_ID, authUserId)
                    .withClaim(ProfitMandiConstants.AUTH_USER_EMAIL, authUserEmail)
                    .withClaim(ProfitMandiConstants.IS_IMPERSONATION, true)
                    .sign(ALGORITHM);
        } catch (JWTCreationException jwtCreationException) {
            throw new RuntimeException(ResponseCodeHolder.getMessage("USR_1011"));
        }
    }

    public String create(String email) {
        try {
            return createBuilder().withClaim(EMAIL, email).sign(ALGORITHM);
        } catch (JWTCreationException jwtCreationException) {
            throw new RuntimeException(ResponseCodeHolder.getMessage("USR_1011"));
        }
    }
    public String create() {
        String email = "unregistereduser@gmail.com";

        try {
            return this.createBuilder().withClaim("email", email).sign(ALGORITHM);
        } catch (JWTCreationException var3) {
            throw new RuntimeException(ResponseCodeHolder.getMessage("USR_1011"));
        }
    }

    private Builder createBuilder() {
        Instant createTimestamp = Instant.now();
        Instant expireTimestamp = Instant.now().plusSeconds(EXPIRE_TIME_IN_SECONDS);
        //LOGGER.info("Creating token with issuer {}, issuedAt {}, expireAt {}", PROFIT_MANDI, createTimestamp.toString(), expireTimestamp.toString());
        return JWT.create()
                .withIssuer(PROFIT_MANDI)
                .withIssuedAt(Date.from(createTimestamp))
                .withExpiresAt(Date.from(expireTimestamp));
    }

    public boolean isExpired(String token)
            throws ProfitMandiBusinessException {
        DecodedJWT decodedJWT = parse(token);
        Map<String, Claim> claims = decodedJWT.getClaims();
        if (claims.containsKey(USER_ID)) {
            final Claim roleIdsClaim = claims.get(ProfitMandiConstants.ROLE_IDS);
            if (roleIdsClaim.isNull()) {
                return true;
            }
        }
        Instant expireTime = decodedJWT.getExpiresAt().toInstant();
        Instant currentTime = Instant.now();
        //LOGGER.info("Checking token Expire time of token {} with currentTime {}, expireTime {}", token, currentTime, expireTime);
        if (currentTime.toEpochMilli() > expireTime.toEpochMilli()) {
            return true;
        } else {
            return false;
        }
    }

    public UserInfo getUserInfo(String token)
            throws ProfitMandiBusinessException {
        LOGGER.info("Getting UserInfo from token {}", token);
        DecodedJWT decodedJWT = parse(token);
        Map<String, Claim> claims = decodedJWT.getClaims();
        LOGGER.info("Claims contains user id - {}", claims.containsKey(USER_ID));
        if (claims.containsKey(USER_ID)) {
            final Claim userIdclaim = claims.get(USER_ID);
            int userId = userIdclaim.asInt();
            final Claim retailerIdclaim = claims.get(ProfitMandiConstants.RETAILER_ID);
            int retailerId = retailerIdclaim.asInt();
            final Claim roleIdsClaim = claims.get(ProfitMandiConstants.ROLE_IDS);
            if (roleIdsClaim == null || roleIdsClaim.isNull()) {
                throw new ProfitMandiBusinessException("Token", token, "Invalid Token");
            }
            String emailId = null;
            if (claims.containsKey(ProfitMandiConstants.EMAIL_ID)) {
                emailId = claims.get(ProfitMandiConstants.EMAIL_ID).asString();
            }
            final UserInfo userInfo = new UserInfo(userId, retailerId, new HashSet<>(Arrays.asList(roleIdsClaim.asArray(Integer.class))), emailId);
            if (claims.containsKey(ProfitMandiConstants.IS_IMPERSONATION)
                    && !claims.get(ProfitMandiConstants.IS_IMPERSONATION).isNull()
                    && claims.get(ProfitMandiConstants.IS_IMPERSONATION).asBoolean()) {
                userInfo.setImpersonation(true);
                userInfo.setAuthUserId(claims.get(ProfitMandiConstants.AUTH_USER_ID).asInt());
                userInfo.setAuthUserEmail(claims.get(ProfitMandiConstants.AUTH_USER_EMAIL).asString());
            }
            return userInfo;
        } else if (claims.containsKey(EMAIL)) {
            final Claim emailClaim = claims.get("email");
            String email = emailClaim.asString();
            int retailerId = -1;
            if(email.contains("unregistereduser@gmail.com")) {
                try {
                    retailerId = partnerTypeChangeService.getBestPartner(ProfitMandiConstants.WAREHOUSE_NAME_MAP.get("RJ"));
                    LOGGER.info("Best partner for unregistered user is {}", retailerId);
                } catch (Exception e) {
                    LOGGER.error("Error while getting best partner for unregistered user", e);
                }
            }
            return new UserInfo(-1, retailerId, null, email);

        } else {
            throw new ProfitMandiBusinessException(ProfitMandiConstants.TOKEN, token, "USR_1008");
        }
    }

    public List<String> getRoleNames(String token)
            throws ProfitMandiBusinessException {
        DecodedJWT decodedJWT = parse(token);
        Map<String, Claim> claims = decodedJWT.getClaims();
        if (claims.containsKey(ProfitMandiConstants.ROLE_IDS)) {
            Claim claim = claims.get(ProfitMandiConstants.ROLE_IDS);
            return Arrays.asList(claim.asArray(String.class));
        } else {
            throw new ProfitMandiBusinessException(ProfitMandiConstants.TOKEN, token, "USR_1009");
        }
    }

    private DecodedJWT parse(String token)
            throws ProfitMandiBusinessException {
        try {
            JWTVerifier verifier = JWT.require(ALGORITHM)
                    .withIssuer(PROFIT_MANDI).acceptExpiresAt(100000000)
                    .build(); //Reusable verifier instance
            return verifier.verify(token);
        } catch (JWTDecodeException exception) {
            throw new ProfitMandiBusinessException(ProfitMandiConstants.TOKEN, token, "USR_1010");
        } catch (InvalidClaimException invalidClaimException) {
            throw new ProfitMandiBusinessException(ProfitMandiConstants.TOKEN, token, "USR_1012");
        }
    }

    public void main(String[] args) throws Throwable {
        JWTUtil jwtUtil = new JWTUtil();
        String token = jwtUtil.create("amit.gupta@shop2020.in");
        //System.out.println(token);
        //System.out.println(JWTUtil.isExpired(token));
        //System.out.println(JWTUtil.getUserInfo(token));
        DecodedJWT decodeJwt = jwtUtil.parse("eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwcm9maXRtYW5kaSIsImV4cCI6MTUxNDk3MDY4OSwiaWF0IjoxNTA5Nzg2Njg5LCJ1c2VySWQiOjMzMjM1LCJyb2xlTmFtZXMiOlsiVVNFUiJdfQ.C1lE6XvGpvQaCISG4IlJKwzEYWa3dWMLn1jXKB7fFvc");
        System.out.println(decodeJwt.getExpiresAt());
    }
}