Subversion Repositories SmartDukaan

Rev

Rev 31238 | Rev 32570 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.controller;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.Location;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.ProfitMandiResponse;
import com.spice.profitmandi.common.web.client.RestClient;
import com.spice.profitmandi.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.dtr.*;
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
import com.spice.profitmandi.dao.entity.user.Device;
import com.spice.profitmandi.dao.enumuration.dtr.AccountType;
import com.spice.profitmandi.dao.enumuration.dtr.RoleType;
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
import com.spice.profitmandi.dao.repository.catalog.DeviceRepository;
import com.spice.profitmandi.dao.repository.dtr.*;
import com.spice.profitmandi.service.AuthService;
import com.spice.profitmandi.service.authentication.RoleManager;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;
import com.spice.profitmandi.web.util.GoogleTokenUtil;
import com.spice.profitmandi.web.util.MVCResponseSender;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@Transactional
public class LoginController {

        private static final Logger LOGGER = LogManager.getLogger(LoginController.class);

        @Autowired
        private GoogleTokenUtil googleTokenUtil;

        @Autowired
        private RoleManager roleManager;

        @Autowired
        private DeviceRepository deviceRepository;

        @Autowired
        private RetailerRepository retailerRepository;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private UserRepository userRepository;

        @Autowired
        private UserAccountRepository userAccountRepository;

        @Autowired
        private UserRoleRepository userRoleRepository;

        @Autowired
        private RoleRepository roleRepository;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;

        @Autowired
        private MVCResponseSender mvcResponseSender;

        @Autowired
        private RestClient restClient;

        @Autowired
        private CookiesProcessor cookiesProcessor;

        @Value("${google.api.key}")
        private String googleApiKey;
        
        @Value("${app.token.url}")
        private String appTokenUrl;
        
        @Value("${angular.app.url}")
        private String appUrl;
        
        @Value("${admin.token}")
        private String adminToken;

        @Autowired
        private AuthService authService;

        @Autowired
        private AuthRepository authRepository;

        @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String loginPage(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
                LOGGER.info("Context Path is {}", request.getContextPath());
                try {
                        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
                        LOGGER.info("Request session is already exist, should be redirect to as per roles assigned");
                        String redirectUrl = null;

                        Role roleRetailer = roleRepository.selectByName(RoleType.RETAILER.toString());
                        Role roleFofo = roleRepository.selectByName(RoleType.FOFO.toString());
                        Role roleFofoAdmin = roleRepository.selectByName(RoleType.FOFO_ADMIN.toString());
                        if (fofoDetails.getRoleIds().contains(roleFofoAdmin.getId())) {
                                redirectUrl = "/dashboard";
                        } else if (fofoDetails.getRoleIds().contains(roleRetailer.getId())
                                        && fofoDetails.getRoleIds().contains(roleFofo.getId())) {
                                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoDetails.getFofoId());
                                if (!fofoStore.isActive()) {
                                        cookiesProcessor.removeCookies(request, response);
                                        throw new ProfitMandiBusinessException("", "", "");
                                }
                                redirectUrl = "/dashboard";

                        } else {
                                redirectUrl = "/login";
                        }
                        return "redirect:" + redirectUrl;
                } catch (ProfitMandiBusinessException profitMandiBusinessException) {
                        model.addAttribute("googleApiKey", googleApiKey);
                        model.addAttribute("appContextPath", request.getContextPath());
                        return "login";
                }
        }

        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String home() {
                return "redirect:/login";
        }

        @RequestMapping(value = "/mobileapp", method = RequestMethod.GET)
        public String mobileApp(HttpServletRequest request, Model model, @RequestParam(defaultValue = "") String emailId)
                        throws Exception {
                LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
                if (roleManager.isAdmin(fofoDetails.getRoleIds())) {
                        if (emailId.equals("")) {
                                AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
                                model.addAttribute("authToken", getToken(authUser.getGmailId()));
                        } else {
                                model.addAttribute("authToken", getToken(emailId));
                                model.addAttribute("androidId", getAndroidId(emailId));
                        }
                } else {
                        emailId = fofoDetails.getEmailId();
                        model.addAttribute("authToken", getToken(emailId));
                        model.addAttribute("androidId", getAndroidId(emailId));
                }
                model.addAttribute("appUrl", appUrl);
                return "mobileapp";
        }

        private String getAndroidId(String emailId) throws Exception {
                User user = userRepository.selectByEmailId(emailId);
                List<Device> devices = deviceRepository.selectByUserIdAndModifiedTimestamp(Arrays.asList(user.getId()),
                                LocalDateTime.now().minusYears(2), LocalDateTime.now());
                if (devices.size() > 0) {
                        Device device = devices.get(0);
                        return device.getAndroidId();
                } else {
                        return "";
                }
        }

        private String getToken(String emailId) throws Exception {
                List<NameValuePair> nameValuePairs = new ArrayList<>();
                nameValuePairs.add(new BasicNameValuePair("adminToken", this.adminToken));
                nameValuePairs.add(new BasicNameValuePair("emailId", emailId));
                String queryString = URLEncodedUtils.format(nameValuePairs, "UTF-8");
                String response = restClient.post(this.appTokenUrl + queryString,
                                new HashMap<>(), new HashMap<>());
                Type t = new TypeToken<ProfitMandiResponse<Map<String, Object>>>() {
                }.getType();
                ProfitMandiResponse<Map<String, Object>> apiResponse = new Gson().fromJson(response, t);
                if (apiResponse.getStatusCode().equals("200")) {
                        return (new StringBuilder((String) apiResponse.getResponse().get("token")).reverse().toString());
                } else {
                        throw new Exception("Unauthorised access");
                }

        }

        @RequestMapping(value = "/login-as-partner", method = RequestMethod.GET)
        public String adminLogin(HttpServletRequest request, Model model, HttpServletResponse response,
                        @RequestParam int fofoId) throws Exception {
                LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
                if (roleManager.isAdmin(fofoDetails.getRoleIds())) {
                        int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
                        User user = userRepository.selectById(userId);
                        Set<Integer> roleIds = userRoleRepository.selectByUserId(userId).stream().map(x -> x.getRoleId())
                                        .collect(Collectors.toSet());
                        LoginDetails newFofoDetails = new LoginDetails();
                        newFofoDetails.setFofoId(fofoId);
                        newFofoDetails.setRoleIds(roleIds);
                        newFofoDetails.setEmailId(user.getEmailId());
                        model.addAttribute("response1", true);
                        this.addCookiesToResponse(newFofoDetails, request, response);
                } else {
                        throw new ProfitMandiBusinessException("", "", "");
                }
                return "response";
        }
        
        @RequestMapping(value = "/login-as-partner-readonly", method = RequestMethod.GET)
        public String readonlyLogin(HttpServletRequest request, Model model, HttpServletResponse response,
                        @RequestParam int fofoId) throws Exception {
                LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
                if (roleManager.isAdmin(fofoDetails.getRoleIds())) {
                        int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
                        User user = userRepository.selectById(userId);
                        Set<Integer> roleIds = userRoleRepository.selectByUserId(userId).stream().map(x -> x.getRoleId())
                                        .collect(Collectors.toSet());
                        LoginDetails newFofoDetails = new LoginDetails();
                        newFofoDetails.setFofoId(fofoId);
                        newFofoDetails.setRoleIds(roleIds);
                        newFofoDetails.setEmailId(user.getEmailId());
                        newFofoDetails.setReadOnly(true);
                        model.addAttribute("response1", true);
                        this.addCookiesToResponse(newFofoDetails, request, response);
                } else {
                        throw new ProfitMandiBusinessException("", "", "");
                }
                return "response";
        }

        @RequestMapping(value = "/login", method = RequestMethod.POST)
        public String login(HttpServletRequest request, HttpServletResponse response,
                        @RequestParam(name = ProfitMandiConstants.TOKEN) String token,
                        @RequestParam(name = ProfitMandiConstants.EMAIL_ID_OR_MOBILE_NUMBER, defaultValue = "") String emailIdOrMobileNumber,
                        @RequestParam(name = "password", defaultValue = "") String password, Model model) throws Exception {

                LoginDetails fofoDetails = new LoginDetails();
                Set<Integer> roleIds = new HashSet<>();
                fofoDetails.setRoleIds(roleIds);
                String emailId = null;
                String name = null;
                try {
                        // if role is retailer then FOFO_ID is retailerId else it is userid as normal
                        // user's wont have retailer id.
                        if (token == "") {
                                if (authService.authenticate(emailIdOrMobileNumber, password)) {
                                        AuthUser authUser = authRepository.selectByEmailOrMobile(emailIdOrMobileNumber);
                                        if (authUser == null) {
                                                throw new ProfitMandiBusinessException("Authentication", "Email or Mobile",
                                                                "Invalid Email Or Mobile");
                                        }
                                        emailId = authUser.getEmailId();
                                        name = authUser.getFirstName() + " " + authUser.getLastName();
                                        authUser.setLastLoginTimestamp(LocalDateTime.now());
                                        authRepository.persist(authUser);
                                }

                        } else {
                                try {
                                        emailId = googleTokenUtil.getEmailId(token);
                                } catch (Exception e) {
                                        // in case we cannot connect to google server.
                                        emailId = emailIdOrMobileNumber;
                                }
                        }
                        fofoDetails.setEmailId(emailId);
                        fofoDetails.setFofoId(-1);
                        // fofoDetails.setFofo(false);
                        User user = null;
                        try {
                                user = userRepository.selectByEmailId(emailId);
                        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
                                LOGGER.error("User not found with given emailId [{}]", emailId);
                        }
                        if (user == null) {
                                try {
                                        user = userRepository.selectBySecondryEmailId(emailId);
                                } catch (ProfitMandiBusinessException profitMandiBusinessException) {
                                        LOGGER.error("User not found with given emailId", profitMandiBusinessException);
                                        model.addAttribute("response1", mvcResponseSender.createResponseString("RTLR_OK_1002", true,
                                                        request.getContextPath() + "/login", "Email"));
                                        return "response";
                                }
                        }
                        if (user != null) {
                                fofoDetails.setFofoId(user.getId());
                                try {
                                        List<UserRole> userRoles = userRoleRepository.selectByUserId(user.getId());
                                        for (int index = 0; index < userRoles.size(); index++) {
                                                roleIds.add(userRoles.get(index).getRoleId());
                                        }
                                        List<Role> roles = roleRepository.selectByIds(roleIds);
                                        for (Role role : roles) {
                                                if (role.getName().equals(RoleType.RETAILER.toString())) {
                                                        UserAccount userAccounts = userAccountRepository.selectByUserIdType(user.getId(),
                                                                        AccountType.saholic);
                                                        Retailer retailer = retailerRepository.selectById(userAccounts.getAccountKey());
                                                        fofoDetails.setFofoId(retailer.getId());
                                                        // fofoDetails.setFofo(retailer.isFofo());
                                                }
                                        }
                                } catch (ProfitMandiBusinessException pmbe) {
                                        LOGGER.error("Data Inconsistent", pmbe);
                                }
                        }
                        String redirectUrl = null;

                        Role roleFofo = roleRepository.selectByName(RoleType.FOFO.toString());
                        Role roleFofoAdmin = roleRepository.selectByName(RoleType.FOFO_ADMIN.toString());

                        if (fofoDetails.getRoleIds().contains(roleFofo.getId())) {
                                redirectUrl = "/dashboard";
                                if (fofoDetails.getRoleIds().contains(roleFofo.getId())) {

                                }
                        } else {
                                redirectUrl = "/login";
                        }

                        if (redirectUrl.equals("/dashboard")) {
                                user.setLoginTimestamp(LocalDateTime.now());
                                this.addCookiesToResponse(fofoDetails, request, response);
                                LOGGER.info("Requested token email_id is valid, user login to system, shoud be redirect to {}",
                                                redirectUrl);
                                model.addAttribute("response1", mvcResponseSender.createResponseString("RTLR_OK_1002", true,
                                                request.getContextPath() + redirectUrl, name));
                        } else {
                                LOGGER.error("Requested token email_id is not valid, please try to login");
                                /**
                                 * TODO:Amit This redirect should be handle.
                                 */
                                throw new ProfitMandiBusinessException(ProfitMandiConstants.EMAIL_ID, fofoDetails.getEmailId(),
                                                "RTLR_1000");
                        }
                        return "response";
                } catch (ProfitMandiBusinessException profitMandiBusinessException) {
                        LOGGER.error("Error : ", profitMandiBusinessException);
                        model.addAttribute("response1",
                                        mvcResponseSender.createResponseString(profitMandiBusinessException.getCode(), false, "/error"));
                        return "response";
                } catch (Exception e) {
                        e.printStackTrace();
                        model.addAttribute("response1",
                                        mvcResponseSender.createResponseString(
                                                        "You are not authorised! " + "Please contact the team if you feel this is incorrect", false,
                                                        "/error"));
                        return "response";
                }
        }

        @PostMapping(value = "/forgetPassword")
        public String forgetPasswordPage(
                        @RequestParam(name = ProfitMandiConstants.EMAIL_ID, defaultValue = "") String emailId, Model model)
                        throws Exception {
                LOGGER.info(emailId);
                authService.resetPassword(emailId);
                model.addAttribute("response1", mvcResponseSender.createResponseString(true));
                LOGGER.info("completed");
                return "response";
        }

        private void addCookiesToResponse(LoginDetails fofoDetails, HttpServletRequest request,
                        HttpServletResponse response) {
                List<String> roleIds = new ArrayList<>();

                for (int roleId : fofoDetails.getRoleIds()) {
                        roleIds.add(String.valueOf(roleId));
                }
                Cookie cookieRoleIds = new Cookie(ProfitMandiConstants.ROLE_IDS, String.join("-", roleIds));
                cookieRoleIds.setDomain(request.getServerName());
                cookieRoleIds.setPath(request.getContextPath());

                Cookie cookieFofoId = new Cookie(ProfitMandiConstants.FOFO_ID, String.valueOf(fofoDetails.getFofoId()));
                cookieFofoId.setDomain(request.getServerName());
                cookieFofoId.setPath(request.getContextPath());

                Cookie cookieEmailId = new Cookie(ProfitMandiConstants.EMAIL_ID, fofoDetails.getEmailId());
                cookieEmailId.setDomain(request.getServerName());
                cookieEmailId.setPath(request.getContextPath());
                
                Cookie cookieReadOnly = new Cookie(ProfitMandiConstants.READONLY_KEY, fofoDetails.isReadOnly() + "");
                cookieReadOnly.setDomain(request.getServerName());
                cookieReadOnly.setPath(request.getContextPath());

                response.addCookie(cookieFofoId);
                response.addCookie(cookieEmailId);
                response.addCookie(cookieRoleIds);
                response.addCookie(cookieReadOnly);
        }

        @RequestMapping(value = "/logout", method = RequestMethod.GET)
        public String logout(HttpServletRequest request, @ModelAttribute("model") ModelMap model,
                        HttpServletResponse response) throws Exception {
                try {
                        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                        User user = null;
                        try {
                                user = userRepository.selectByEmailId(loginDetails.getEmailId());
                        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
                                LOGGER.error("User not found with given emailId", profitMandiBusinessException);
                        }
                        if (user == null) {
                                user = userRepository.selectBySecondryEmailId(loginDetails.getEmailId());
                        }
                        user.setLogoutTimestamp(LocalDateTime.now());
                        userRepository.persist(user);
                        cookiesProcessor.removeCookies(request, response);
                        LOGGER.info("Logout is successfull, should be redirect to /login");
                        return "redirect:/login";
                } catch (ProfitMandiBusinessException profitMandiBusinessException) {
                        LOGGER.info("Error occured while removing requested cookies, should be redirect to /login");
                        return "redirect:/login";
                }
        }

        @RequestMapping(value = "/partner/location", method = RequestMethod.PUT)
        public String setLocation(HttpServletRequest request, Model model, @RequestBody Location location)
                        throws Exception {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                boolean response = true;
                try {
                        FofoStore fs = fofoStoreRepository.selectByRetailerId(loginDetails.getFofoId());
                        if (fs.getLatitude() == null) {
                                fs.setLatitude(location.getLatitude());
                                fs.setLongitude(location.getLongitude());
                        }
                        model.addAttribute("response1", response);
                } catch (Exception e) {
                        LOGGER.error("FofoStore Code not found of fofoId {}", loginDetails.getFofoId());
                }
                return "response";
        }
}