Advertisement
naimul64

AuthenitcationController

Mar 18th, 2018
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Groovy 24.92 KB | None | 0 0
  1. package com.progoti.surecash.security
  2.  
  3. import com.google.gson.Gson
  4. import com.google.gson.reflect.TypeToken
  5. import com.progoti.PropertiesReader
  6. import com.progoti.bean.RedirProperties
  7. import com.progoti.surecash.dto.member.UserLookUpResponse
  8. import com.progoti.surecash.exception.SystemException
  9. import com.progoti.surecash.home.DashboardService
  10. import com.progoti.surecash.merchant.PinlessWallet
  11. import com.progoti.surecash.rest.ResfullAPIServices
  12. import com.progoti.surecash.soap.ProfinoWebServices
  13. import com.progoti.surecash.soap.service.LoginStatus
  14. import com.progoti.surecash.user.*
  15. import com.progoti.surecash.util.EncryptionUtils
  16. import com.progoti.surecash.util.ProTraceLevel
  17. import com.progoti.switchable.Environment
  18. import org.apache.commons.lang.StringUtils
  19. import org.apache.log4j.LogManager
  20. import org.apache.log4j.Logger
  21. import org.json.JSONObject
  22.  
  23. import javax.xml.ws.WebServiceException
  24.  
  25. //import java.util.logging.Level
  26. //import java.util.logging.Logger
  27. class AuthenticationController {
  28.     def securityService
  29.     DashboardService dashboardService;
  30.     AuthenticationService authenticationService;
  31.     ScAuthorityService scAuthorityService;
  32.     ScUserGroupService scUserGroupService;
  33.     ScUserService scUserService;
  34.     def billerInfoService;
  35.     def fingerprintService
  36.     WalletCodeService walletCodeService;
  37.     ObviousPinsService obviousPinsService;
  38.  
  39.     private static final Logger logger = LogManager.getLogger(AuthenticationController.class.getName());
  40.  
  41.     def index = {}
  42.  
  43.     def login = {
  44.  
  45.         if (session.UserName != null && session.PIN != null && session?.isActive) {
  46.             redirect(controller: "home", action: "dashboard");
  47.         } else {
  48.             def targetUri = params.targetUri;
  49.             try {
  50.                 if (params.targetUri != null) {
  51.                     response.setHeader(params.targetUri, "")
  52.                 }
  53.             } catch (Exception ex) {
  54.                 logger.error(ProTraceLevel.PRO_TRACE, ex);
  55.             }
  56.             render(view: "/auth/progoti_login", model: [targetUri: targetUri]);
  57.         }
  58.     }
  59.  
  60.  
  61.     def merchantAdminPage(){
  62.         render(view: "/agentAccountReg/list")
  63.     }
  64.  
  65.     def getAuthenticationByPushInfo(String wallet) {
  66.         boolean isWalletHolder = true;
  67.         boolean allowedWithoutPinCheck = true;
  68.         UserLookUpResponse walletInfo = null;
  69.         try {
  70.             // search the given wallet/ID among wallets on switch
  71.             walletInfo = ResfullAPIServices.getUserInfoFromSwitch(wallet, isWalletHolder);
  72.         } catch (ClassNotFoundException ex) {
  73.             def loginStatus = LoginStatus.LoginValidationStatus.CLASS_NOT_FOUND;
  74.             logger.error(ProTraceLevel.PRO_TRACE, ex);
  75.         }
  76.  
  77.         if (walletInfo != null && walletInfo.getStatus().equalsIgnoreCase("SUCCESS")) {
  78.             String userType = walletInfo.userType;
  79.             String requiredAccountTypes = PropertiesReader.getProperty("user.type.require.phone.validation", "unbanked");
  80.             String[] types = requiredAccountTypes?.split(",");
  81.  
  82.             for (String type : types) {
  83.                 if (type.equalsIgnoreCase(userType)) {
  84.                     allowedWithoutPinCheck = false;
  85.                     break;
  86.                 }
  87.             }
  88.         }
  89.  
  90.         List<PinlessWallet> pinlessWallets = PinlessWallet.findAllByIsActiveAndAllowLoginAndWalletNo(true, true,wallet);
  91.         if(pinlessWallets!=null && pinlessWallets.size()>0){
  92.             allowedWithoutPinCheck=true;
  93.         }
  94.  
  95.  
  96.         JSONObject json = new JSONObject();
  97.         if(allowedWithoutPinCheck){
  98.             json.put("status", true);
  99.         }else{
  100.             json.put("status", false);
  101.         }
  102.  
  103.         response.setContentType("application/json");
  104.         PrintWriter out = response.getWriter();
  105.         out.println(json.toString());
  106.         out.flush();
  107.         out.close();
  108.         return;
  109.     }
  110.  
  111.     def authenticate = {
  112.  
  113.         String credentialValidityStatus = "";
  114.         Boolean isPushRequired=true;
  115.         String wallet=params?.merchant;
  116.         session.LoginbyMerchantAdmin = null
  117.         if(session?.UserType.toString().equalsIgnoreCase("merchantAdmin") || session?.UserType.toString().equalsIgnoreCase("MAD")){
  118.             session.LoginbyMerchantAdmin = session.UserName
  119.             if(session?.UserType.toString().equalsIgnoreCase("MAD")){
  120.                 wallet=params?.id;
  121.             }
  122.             String pin = session.PIN;
  123.             if(wallet != null){
  124.                 Environment.setEnvironmentByBank(session?.UserBankName)
  125.                 pin = fingerprintService.getPinByWallet(wallet)
  126.                 params.userName= wallet
  127.                 params.password=pin
  128.                 session.UserName=null
  129.                 session.PIN=null
  130.             }
  131.             isPushRequired=false
  132.         }
  133.         if(session?.UserType.toString().equalsIgnoreCase("merchantAdmin")){
  134.             String pin = session.PIN;
  135.             if(wallet != null){
  136.                 Environment.setEnvironmentByBank(session?.merchantBank)
  137.                 pin = fingerprintService.getPinByWallet(wallet)
  138.                 params.userName= wallet
  139.                 params.password=pin
  140.                 session.UserName=null
  141.                 session.PIN=null
  142.             }
  143.             isPushRequired=false
  144.         }
  145.         boolean haveWalletShortCode = false;
  146.  
  147. //        if(wallet!=null && wallet.equalsIgnoreCase("nbsm")){
  148. //            wallet="017743543567";
  149. //        }
  150. //
  151. //        if(wallet!=null && wallet.equalsIgnoreCase("ntsm")){
  152. //            wallet="019902776772";
  153. //        }
  154. //
  155. //        if(wallet!=null && wallet.equalsIgnoreCase("rjsm")){
  156. //            wallet="015510865999";
  157. //        }
  158. //
  159. //        if(wallet!=null && wallet.equalsIgnoreCase("fsm")){
  160. //            wallet="019754688745";
  161. //        }
  162.         if (session.UserName != null && session.PIN != null && session?.isActive) {
  163.             RedirProperties redirProperties = dashboardService.getRedirProperties(session, "home", "dashboard");
  164.             redirect(controller: redirProperties.getControllerName(), action: redirProperties.getActionName());
  165.         } else {
  166.             ////////////////
  167.             String userName = params.userName != null && params.userName != "" ? ((String) params.userName)?.trim() : "";
  168.             String password = params.password != null && params.password != "" ? ((String) params.password)?.trim() : "";
  169.             Object user;
  170.             String userType;
  171.             session.isActive = false;
  172.             List<ScUserGroup> userGroups = new ArrayList<ScUserGroup>();
  173.             List<ScAuthority> userAuthorities = new ArrayList<ScAuthority>();
  174.  
  175.  
  176.             UserLookUpResponse walletInfo = null;
  177.             String loginStatusMesg = PropertiesReader.getResponseMesgByErrCode(LoginStatus.LoginValidationStatus.UNABLE_TO_CONNECT_SWITCH);
  178.             LoginStatus.LoginValidationStatus loginStatus = LoginStatus.LoginValidationStatus.UNABLE_TO_CONNECT_SWITCH;
  179.             if ((userName != null && !userName.equals("")) && (password != null && !password.equals(""))) { // empty chk
  180.  
  181.                 loginStatus = LoginStatus.LoginValidationStatus.UNABLE_TO_CONNECT_SWITCH;
  182.                 boolean isWalletHolder = true;
  183.  
  184.                 try {
  185.                     // search the given wallet/ID among wallets on switch
  186.                     walletInfo = ResfullAPIServices.getUserInfoFromSwitch(userName, isWalletHolder);
  187.                 } catch (ClassNotFoundException ex) {
  188.                     loginStatus = LoginStatus.LoginValidationStatus.CLASS_NOT_FOUND;
  189.                     logger.error(ProTraceLevel.PRO_TRACE, ex);
  190.                 }
  191.  
  192.  
  193.                 if (walletInfo != null && walletInfo.getStatus().equalsIgnoreCase("SUCCESS")) {
  194.                     Environment.setEnvironmentByBank(walletInfo.bankName);
  195.                     ObviousPins obviousPin = obviousPinsService.findByPin(password);
  196.                     if(!session?.UserType.toString().equalsIgnoreCase("merchantAdmin") && obviousPin != null){
  197.                         loginStatus = LoginStatus.LoginValidationStatus.OBVIOUS_PIN_FOUND;
  198.                         flash.message = PropertiesReader.getResponseMesgByErrCode(loginStatus);
  199.                         redirect(controller: "authentication", action: "login");
  200.                         return false;
  201.                     }
  202.                     List<PinlessWallet> pinlessWallets = PinlessWallet.findAllByIsActiveAndAllowLoginAndWalletNo(true, true,userName);
  203.                     if(pinlessWallets!=null && pinlessWallets.size()>0){
  204.                         isPushRequired=false;
  205.                     }
  206.                     // setting bank specific data source.
  207.                     //EnvironmentHolder.setEnvironment(Environment.list().get(Integer.parseInt(walletInfo.bankId) - 1));
  208.  
  209.                     isPushRequired = false
  210.                     if(isPushRequired && !authenticationService.authenticatePinByPush(walletInfo)){
  211.                         flash.message = "Invalid PIN provided on phone";
  212.                         redirect(controller: "authentication", action: "login");
  213.                         return false;
  214.                     }
  215.  
  216.                     try {
  217.                         loginStatus = authenticationService.doLoginByProfinoUser(walletInfo, userName, password, session);
  218.                         loginStatus = LoginStatus.LoginValidationStatus.VALID
  219.  
  220.                         // wallet found on bank-specific profino
  221.                         if (loginStatus.compareTo(LoginStatus.LoginValidationStatus.VALID) == 0) {
  222.                             try {
  223.  
  224.                                 user = ProfinoWebServices.loadByUsername(userName, walletInfo.getBankName());
  225.  
  226.                             } catch (WebServiceException ex) {
  227.                                 throw new SystemException(LoginStatus.LoginValidationStatus.UNABLE_TO_CONNECT_PROFINO);
  228.                             } catch (Exception ex) {
  229.                                 throw new SystemException(LoginStatus.LoginValidationStatus.SOAP_FAULT_EXCEPTION);
  230.                             }
  231.                             if (user == null) {
  232.                                 throw new SystemException(LoginStatus.LoginValidationStatus.MEMBER_NOT_FOUND);
  233.                             }
  234.                             Long groupId = ((com.progoti.surecash.webservices.members.Member) user).getGroupId();
  235.                             HashMap memberMap = ProfinoWebServices.memberListToHashMap((com.progoti.surecash.webservices.members.Member) user);
  236.  
  237.                             if (((String) memberMap.get("status")).equalsIgnoreCase("active")) {
  238.                                 session.isActive = true;
  239.                                 ///******Setting session of logged in profino member ******/////
  240.                                 userType = memberMap.containsKey("userType") && !memberMap?.get("userType").equals("") ? memberMap?.get("userType") : null
  241.                                 authenticationService.setLoginSessionForProfinoMember(session, password, memberMap);
  242.  
  243.                                 if (userType?.equalsIgnoreCase("banked") || userType?.equalsIgnoreCase("employee")
  244.                                         || userType?.equalsIgnoreCase("merchant") || userType?.equalsIgnoreCase("remitter")
  245.                                         || userType?.equalsIgnoreCase("unbanked") || userType?.equalsIgnoreCase("MR") || userType?.equalsIgnoreCase("MAD")) {
  246.                                     userAuthorities?.add(scAuthorityService.findByRoleTitle(userType));
  247.  
  248.                                     //get and set session feature of logged user
  249.                                     scAuthorityService.getApprovedFeatureByUserGroups(session, userGroups, userType, userAuthorities);
  250.  
  251.                                 } else {
  252.                                     ScUserGroup scUserGroup = scUserGroupService.findByGroupId(groupId);
  253.  
  254.                                     if (scUserGroup != null) {
  255.                                         userGroups?.add(scUserGroup);
  256.                                         //get and set session feature of logged user
  257.                                         scAuthorityService.getApprovedFeatureByUserGroups(session, userGroups, userType, userAuthorities);
  258.                                     } else {
  259.                                         logger.log(ProTraceLevel.PRO_TRACE, "User [" + userName + "] have tried to login which have no valid userGroup.");
  260.                                     }
  261.                                 }
  262. //                                //get and set session feature of logged user
  263. //                                scAuthorityService.getApprovedFeatureByUserGroups(session,userGroups,userType,userAuthorities);
  264.                             } else {
  265.                                 loginStatus = LoginStatus.LoginValidationStatus.NOT_ACTIVE_USER;
  266.                             }
  267.                         }
  268.                     } catch (SystemException ex) {
  269.                         logger.error(ProTraceLevel.PRO_TRACE, ex);
  270. //                        LOGGER.log(Level.SEVERE, null, ex);
  271.                         if (ex.getErrorCode() == LoginStatus.LoginValidationStatus.UNABLE_TO_CONNECT_PROFINO) {
  272.                             loginStatus = LoginStatus.LoginValidationStatus.UNABLE_TO_CONNECT_PROFINO
  273.                         } else if (ex.getErrorCode() == LoginStatus.LoginValidationStatus.SOAP_FAULT_EXCEPTION) {
  274.                             loginStatus = LoginStatus.LoginValidationStatus.SOAP_FAULT_EXCEPTION
  275.                         } else if (ex.getErrorCode() == LoginStatus.LoginValidationStatus.MEMBER_NOT_FOUND) {
  276.                             loginStatus = LoginStatus.LoginValidationStatus.MEMBER_NOT_FOUND
  277.                         }
  278.                     }
  279.                 } else {  // if wallet not found on switch's master table
  280.                     try {
  281.                         // Given username is not a valid wallet
  282.                         // so search among custom users on switch
  283.                         isWalletHolder = false;
  284.                         walletInfo = ResfullAPIServices.getUserInfoFromSwitch(userName, isWalletHolder);
  285.                         session.setAttribute("merchantBank",walletInfo.bankName)
  286.                     } catch (ClassNotFoundException ex) {
  287.                         logger.error(ProTraceLevel.PRO_TRACE, ex);
  288.                         loginStatus = LoginStatus.LoginValidationStatus.CLASS_NOT_FOUND;
  289. //                    LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
  290.                     }
  291.                     // if custom users found on switch
  292.                     if (walletInfo != null && walletInfo.getStatus().equalsIgnoreCase("SUCCESS")) {
  293.  
  294.                         // setting bank specific data source.
  295.                         Environment.setEnvironmentByBank(walletInfo.getBankName());
  296.                         WalletCode walletCode = walletCodeService.findByShortCode(userName);
  297.                         if(walletCode != null){
  298.                             wallet = walletCode.wallet;
  299.                             haveWalletShortCode = true;
  300.                             session.UserName=wallet
  301.                         }
  302.  
  303.                         session.UserBankName = walletInfo.bankName;
  304.                         session.userWalletNo=wallet;
  305.  
  306. //                        if(wallet!=null && (wallet.equalsIgnoreCase("nbsm")||wallet.equalsIgnoreCase("ntsm")||wallet.equalsIgnoreCase("rjsm")||wallet.equalsIgnoreCase("fsm"))){
  307. //                            session.UserName=wallet
  308. //                        }
  309.                         ScUser scUser = null;
  310.                         scUser = scUserService.findByLoginNameAndPassword(userName, EncryptionUtils.encrypt(password));
  311.                         scUser = ScUser.findByLoginName(userName)
  312.  
  313.                         if (scUser != null) {
  314.  
  315.                             if(Boolean.valueOf(PropertiesReader.getProperty("USER_AUTHENTICATION_FOR_NON_WALLET", false))){
  316.  
  317.                                 String response = ResfullAPIServices.getUserInfoForNonWallet(userName);
  318.                                 HashMap<String, Object> map = new Gson().fromJson(response, new TypeToken<HashMap<String, String>>(){}.getType());
  319.  
  320.                                 if(StringUtils.isBlank(map.get("mobilePhone")) && Boolean.valueOf(PropertiesReader.getProperty("USER_AUTHENTICATION_IF_NOT_MOBILE_NO_FOUND",false))){
  321.                                     flash.message = "No Mobile number found. Please Contact with admin";
  322.                                     redirect(action: "login");
  323.                                     return false;
  324.  
  325.                                 }
  326.                                 else if(StringUtils.isNotBlank(map.get("mobilePhone"))){
  327.  
  328.                                     String walletGeneration = map.get("mobilePhone") + String.valueOf((char)(new Random().nextInt(26) + (int)'a'));
  329.  
  330.                                     walletInfo.setUserId(walletGeneration);
  331.                                     walletInfo.setUserType("banked");
  332.                                     walletInfo?.setBankId(map.get("bankId"));
  333.                                     walletInfo?.setBankName(map.get("bankName"));
  334.  
  335.  
  336.                                     if(!authenticationService.authenticatePinByPush(walletInfo, userName)){
  337.                                         flash.message = "Invalid PIN provided on phone";
  338.                                         redirect(action: "login");
  339.                                         return false;
  340.                                     }
  341.                                 }
  342.  
  343.  
  344.                             }
  345.  
  346.                             userAuthorities.addAll(scUser?.authorities);
  347.                             userGroups.addAll(scUser?.userGroups);
  348.                             if (scUser?.status == 2) {
  349.                                 session.isActive = true;
  350.                                 ///******Setting session of logged in ScUser ******/////
  351.                                 session.user = scUser;
  352.  
  353.                                 if (scUser?.scUserProfile?.photographUrl != null) {
  354.                                     session.setAttribute("UserImageUrl", scUser?.scUserProfile?.photographUrl?.toString()?.trim());
  355.                                 } else {
  356.                                     session.setAttribute("UserImageUrl", null);
  357.                                 }
  358.  
  359.                                 authenticationService.setLoginSessionForScUser(session, scUser);
  360.                             } else {
  361.                                 loginStatus = LoginStatus.LoginValidationStatus.NOT_ACTIVE_USER;
  362.                             }
  363.                             user = scUser;
  364.  
  365.                             //get and set session feature of logged user
  366.                             scAuthorityService.getApprovedFeatureByUserGroups(session, userGroups, userType, userAuthorities);
  367.                         } else {
  368.                             loginStatus = LoginStatus.LoginValidationStatus.INVALID;
  369.                         }
  370.                     } else {
  371. //                        if(walletInfo != null && walletInfo.getMsg() != null && !(walletInfo.getMsg().equalsIgnoreCase(""))){
  372. //                            loginStatus = LoginStatus.LoginValidationStatus.TAKE_RESPONSE_MESG_FROM_SWITCH;
  373. //                        }else{
  374. //                            loginStatus = LoginStatus.LoginValidationStatus.NOT_SURECASH_USER ;
  375. //                        }
  376.                         if (walletInfo != null && walletInfo.getStatus() != null && (walletInfo.getStatus().equalsIgnoreCase("FAILED"))) {
  377.                             loginStatus = LoginStatus.LoginValidationStatus.NOT_SURECASH_USER;
  378.                         }
  379.                     }
  380.                 }
  381.             } else {
  382.                 loginStatus = LoginStatus.LoginValidationStatus.INVALID;
  383.             }
  384.             if (loginStatus.compareTo(LoginStatus.LoginValidationStatus.TAKE_RESPONSE_MESG_FROM_SWITCH) == 0) {
  385.                 loginStatusMesg = walletInfo.getMsg();
  386.             } else {
  387.                 loginStatusMesg = PropertiesReader.getResponseMesgByErrCode(loginStatus);
  388.             }
  389.  
  390.             //check logged in user is WASA
  391.             try {
  392.                 authenticationService.getRemoveWasaFeature(session, user)
  393.             } catch (Exception e) {
  394.                 //ignore
  395.             }
  396.             //END
  397.  
  398.             //check logged in user is link3 merchant
  399.             try {
  400.                 authenticationService.getRemoveLink3Feature(session, user)
  401.             } catch (Exception e) {
  402.                 //ignore
  403.             }
  404.             //END
  405.  
  406.             if(session.LoginbyMerchantAdmin != null){
  407.                 authenticationService.getRemoveFeature(session, user,session.LoginbyMerchantAdmin)
  408.                 authenticationService.addTypeOrWalletSpecificFeature(session, session.LoginbyMerchantAdmin)
  409.             }
  410.             else{
  411.                 if(user != null && (String)session.UserName != null){
  412.                     authenticationService.getRemoveFeature(session, user,(String)session.UserName)
  413.                     authenticationService.addTypeOrWalletSpecificFeature(session, (String)session.UserName)
  414.                 }
  415.             }
  416.  
  417.  
  418.             credentialValidityStatus = loginStatusMesg;
  419.             ///////////////
  420. //            credentialValidityStatus = authenticationService.doAuthentication(params, session);
  421.             if (session.isActive) {
  422.                 if(!isPushRequired){
  423.                     session.requestedController=null;
  424.                     session.requestedAction=null;
  425.                 }
  426.                 if (session.requestedController != null && session.requestedAction != null && !"authenticate".equalsIgnoreCase(session.requestedAction) && !"login".equalsIgnoreCase(session.requestedAction)) {
  427.                     redirect(controller: session.requestedController, action: session.requestedAction, params: params);
  428.                 } else if(session.UserName != null && session?.UserType.toString().equalsIgnoreCase("merchantAdmin")){
  429.                     session.setAttribute("merchantUser",session?.user)
  430.                     redirect(controller: "merchantAdminHome", action: "index");
  431.  
  432.                 } else if(session.UserName != null && session?.UserType.toString().equalsIgnoreCase("stipendAdmin")) {
  433.                     List<ScFeature> approveFeatures = session.getAttribute("approvedFeatures");
  434.                     if(approveFeatures.contains(ScFeature.findByModuleAndOperation("StDisburse", "first"))) {
  435.                         redirect(controller: "StDisburse", action: "first");
  436.                     } else {
  437.                         RedirProperties redirProperties = dashboardService.getRedirProperties(session, "home", "dashboard");
  438.                         redirect(controller: redirProperties.getControllerName(), action: redirProperties.getActionName());
  439.                     }
  440.                 } else {
  441.                     RedirProperties redirProperties = dashboardService.getRedirProperties(session, "home", "dashboard");
  442.                     redirect(controller: redirProperties.getControllerName(), action: redirProperties.getActionName());
  443.                 }
  444.                 return true;
  445.             } else {
  446.                 flash.message = credentialValidityStatus;
  447.                 redirect(action: "login");
  448.  
  449.  
  450.             }
  451.         }
  452.     }
  453.  
  454.     /**
  455.      *  check user permission to view the menu
  456.      * @params - session
  457.      * @params - module as like controller name
  458.      * @params - operator as like permission to access (list/view/show/update/create etc)
  459.      * @return - boolean
  460.      */
  461.     public boolean hasPermission(session, module, operator) {
  462.         boolean retVal = false;
  463.  
  464.         if (operator.equals("") || operator.equals(null)) {
  465.             operator = "index";
  466.         }
  467.         if (securityService.checkAuthorization(session, module, operator)) {
  468.             retVal = true;
  469.         }
  470.         return retVal;
  471.     }
  472.  
  473.     /**
  474.      * getting a unique module list as string from approved feature
  475.      * @param - session
  476.      * @return - List<String>
  477.      */
  478.     public List<String> getUniqueModuleListOfFeatures(session) {
  479.         ScFeatureService featureService = new ScFeatureService();
  480.         return featureService.getUniqueModuleListOfFeatures(session)
  481.     }
  482.     /**
  483.      * getting a feature list by module Name
  484.      * @param - session
  485.      * @param - module as string
  486.      * @return - List<ScFeature>
  487.      */
  488.     public List<ScFeature> getFeatureListByModule(session, String module) {
  489.         ScFeatureService featureService = new ScFeatureService();
  490.         return featureService.getFeatureListByModule(session, module)
  491.     }
  492.  
  493.     /**
  494.      * get menu displayable sorted feature list
  495.      * @param - session
  496.      * @return - List<ScFeature>
  497.      */
  498.     public List<ScFeature> getDisplayableFeatureSortedList(session) {
  499.         ScFeatureService featureService = new ScFeatureService();
  500.         return featureService.getDisplayableFeatureSortedList(session)
  501.     }
  502. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement