diff --git a/GPW_Data/DataProxy.cs b/GPW_Data/DataProxy.cs index 9ed2c13..f9cd77e 100644 --- a/GPW_Data/DataProxy.cs +++ b/GPW_Data/DataProxy.cs @@ -45,48 +45,27 @@ namespace GPW_data #endregion Public Fields - #region Protected Constructors + #region Private Constructors - protected DataProxy() + private DataProxy() { initTA(); setupConnectionStringBase(); } - #endregion Protected Constructors + #endregion Private Constructors #region Public Properties /// /// Verifica se il dip corrente ha un record valido in payload /// - public static bool currDipHasPayloadActive - { - get - { - bool answ = licenzeGPW.userPayloadOk(idxDipendente); - return answ; - } - } + public static bool currDipHasPayloadActive => _currDipHasPayloadActive(); /// /// Verifica se il dip corrente sia attivo /// - public static bool currDipIsActive - { - get - { - bool answ = false; - try - { - DS_Applicazione.DipendentiRow rigaDip = DP.taDipendenti.getByIdx(idxDipendente)[0]; - answ = rigaDip.attivo; - } - catch - { } - return answ; - } - } + public static bool currDipIsActive => _currDipIsActive(); /// /// idxDipendente in sessione @@ -112,12 +91,79 @@ namespace GPW_data #endregion Public Properties - #region Protected Methods + #region Private Methods + + /// + /// Verifica se il dip corrente ha un record valido in payload + /// + private static bool _currDipHasPayloadActive() + { + bool answ = licenzeGPW.userPayloadOk(idxDipendente); + return answ; + } + + /// + /// Verifica se il dip corrente sia attivo + /// + private static bool _currDipIsActive() + { + bool answ = false; + try + { + DS_Applicazione.DipendentiRow rigaDip = DP.taDipendenti.getByIdx(idxDipendente)[0]; + answ = rigaDip.attivo; + } + catch + { } + return answ; + } + + /// + /// Verifica se il dip RICHIESTO sia attivo + /// + /// + /// + private bool checkDipIsActive(int _idxDipendente) + { + bool answ = false; + try + { + DS_Applicazione.DipendentiRow rigaDip = DP.taDipendenti.getByIdx(_idxDipendente)[0]; + answ = rigaDip.attivo; + } + catch + { } + return answ; + } + + /// + /// Calcola HASH del codice impiego + /// + /// + /// + private string getHashCodImpiego(DS_Applicazione.DipendentiRow rigaDip) + { + string hash = ""; + string answ = ""; + if (rigaDip != null) + { + answ = $"{rigaDip.idxDipendente}|{rigaDip.Cognome}.{rigaDip.Nome}|{rigaDip.CF}|{rigaDip.dataAssunzione:yyyyMMdd}|{rigaDip.email}|{rigaDip.matricola}"; + } + // hashing! + using (var md5 = MD5.Create()) + { + byte[] InputBytes = Encoding.UTF8.GetBytes(answ); + var byteHash = md5.ComputeHash(InputBytes); + hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant(); + } + + return hash; + } /// /// init dei table adapters /// - protected void initTA() + private void initTA() { taAnCli = new DS_ApplicazioneTableAdapters.AnagClientiTableAdapter(); taTimb = new DS_ApplicazioneTableAdapters.TimbratureTableAdapter(); @@ -149,7 +195,7 @@ namespace GPW_data /// /// effettua setup dei connection strings da web.config delal singola applicazione /// - protected virtual void setupConnectionStringBase() + private void setupConnectionStringBase() { string connGPW = memLayer.ML.confReadString("GPWConnectionString"); // connections del db @@ -180,7 +226,7 @@ namespace GPW_data taExpComm.Connection.ConnectionString = connGPW; } - #endregion Protected Methods + #endregion Private Methods #region Public Methods @@ -202,18 +248,7 @@ namespace GPW_data /// /// /// - public bool dipIsActive(int _idxDipendente) - { - bool answ = false; - try - { - DS_Applicazione.DipendentiRow rigaDip = DP.taDipendenti.getByIdx(_idxDipendente)[0]; - answ = rigaDip.attivo; - } - catch - { } - return answ; - } + public bool dipIsActive(int _idxDipendente) => checkDipIsActive(_idxDipendente); /// /// effettua enroll del device @@ -300,24 +335,7 @@ namespace GPW_data /// /// /// - public string hashCodImpiego(DS_Applicazione.DipendentiRow rigaDip) - { - string hash = ""; - string answ = ""; - if (rigaDip != null) - { - answ = $"{rigaDip.idxDipendente}|{rigaDip.Cognome}.{rigaDip.Nome}|{rigaDip.CF}|{rigaDip.dataAssunzione:yyyyMMdd}|{rigaDip.email}|{rigaDip.matricola}"; - } - // hashing! - using (var md5 = MD5.Create()) - { - byte[] InputBytes = Encoding.UTF8.GetBytes(answ); - var byteHash = md5.ComputeHash(InputBytes); - hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant(); - } - - return hash; - } + public string hashCodImpiego(DS_Applicazione.DipendentiRow rigaDip) => getHashCodImpiego(rigaDip); /// /// invia una mail al destinatario x linkare nuovi devices tramite URL diff --git a/GPW_Data/licenzeGPW.cs b/GPW_Data/licenzeGPW.cs index 5e16489..e0c8e25 100644 --- a/GPW_Data/licenzeGPW.cs +++ b/GPW_Data/licenzeGPW.cs @@ -15,32 +15,34 @@ namespace GPW_data { public class licenzeGPW { - #region Protected Fields + #region Private Fields + + private static string _applicazione = memLayer.ML.confReadString("appName"); /// /// Url di base chiamate API gestione licenze /// - //protected static string apiUrl = "https://localhost:44351/"; - protected static string apiUrl = "https://liman.egalware.com/ELM.API/"; + //private static string apiUrl = "https://localhost:44351/"; + private static string apiUrl = "https://liman.egalware.com/ELM.API/"; - protected static string rkeyActInfo = memLayer.ML.redHash($"LiMan:ActInfo"); + private static string rkeyActInfo = memLayer.ML.redHash($"LiMan:ActInfo"); - protected static string rkeyAppInfo = memLayer.ML.redHash($"LiMan:AppInfo"); + private static string rkeyAppInfo = memLayer.ML.redHash($"LiMan:AppInfo"); - protected static string rkeyLicInfo = memLayer.ML.redHash($"LiMan:LicInfo"); + private static string rkeyLicInfo = memLayer.ML.redHash($"LiMan:LicInfo"); - protected static string rkeyPayload = memLayer.ML.redHash($"LiMan:Payload"); + private static string rkeyPayload = memLayer.ML.redHash($"LiMan:Payload"); - protected static string rkeyVetoRefPayL = memLayer.ML.redHash($"LiMan:VetoRefPayL"); + private static string rkeyVetoRefPayL = memLayer.ML.redHash($"LiMan:VetoRefPayL"); - #endregion Protected Fields + #endregion Private Fields - #region Protected Properties + #region Private Properties /// /// Durata cache statica locale dati licenza, random circa 1 h /// - protected static int LicCacheTTL + private static int LicCacheTTL { get { @@ -49,354 +51,347 @@ namespace GPW_data } } - #endregion Protected Properties + #endregion Private Properties #region Public Properties /// /// nome applicazione sw /// - public static string applicazione - { - get - { - string answ = memLayer.ML.confReadString("appName"); - return answ; - } - } + public static string applicazione => _applicazione; /// /// numero di licenze attive da info online /// - public static int attivazioniOnline - { - get - { - return InfoApplicativo.NumLicenzeAttive; - } - } + public static int attivazioniOnline => _attivazioniOnline(); /// /// chaive licenza /// - public static string authKey - { - get - { - string answ = ""; - // controllo su db... - try - { - answ = DataProxy.DP.taAKV.getByKey(installazione)[0].valString; - } - catch - { } - return answ; - } - } + public static string authKey => _authKey(); /// /// verifica se numero licenze copre utenti attivi... /// - public static bool checkLicenze - { - get - { - bool answ = false; - try - { - // effettua refresh attivazioni... - var fatto = RefreshActInfo().Result; - answ = utentiAttivi <= licenzeAttive; - if (!answ && memLayer.ML.confReadInt("_logLevel") > 5) - { - logger.lg.scriviLog(string.Format("WARNING licenze: utenti attivi {0} / licenziati {1}", utentiAttivi, licenzeAttive), tipoLog.WARNING); - } - } - catch - { } - return answ; - } - } + public static bool checkLicenze => _checkLicenze(); /// /// verifica se il payload delle licenze attivate sia valido (con server online) /// - public static bool checkPayload - { - get - { - bool answ = false; - string currPayload = ""; - tryCheckPayloadOnline(ref answ, ref currPayload); - - // se OK resetto counter, altrimenti incremento - if (!answ) - { - bool okRefreshPayload = string.IsNullOrEmpty(memLayer.ML.getRSV(rkeyVetoRefPayL)); - if (okRefreshPayload) - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - // richiedo update payload impostando TTL a 1 sec... - memLayer.ML.setRSV(rkeyPayload, "", 1); - var okApp = RefreshAppInfo().Result; - var okLic = RefreshActInfo().Result; - var okAct = RefreshLicInfo().Result; - var okPld = RefreshPayload().Result; - - // evito ricalcolo x 5 sec... - memLayer.ML.setRSV(rkeyVetoRefPayL, "Veto", 5); - sw.Stop(); - logger.lg.scriviLog($"Trovato payload non valido, effettuato reset variabili in {sw.ElapsedMilliseconds} ms"); - - sw.Start(); - tryCheckPayloadOnline(ref answ, ref currPayload); - sw.Stop(); - logger.lg.scriviLog($"Rivalutato payload con esito {answ} in {sw.ElapsedMilliseconds} ms"); - } - } - - return answ; - } - } - - /// - /// Info applicativo corrente (da cache con eventuale recupero online...) - /// - public static LiManObj.ApplicativoDTO InfoApplicativo - { - get - { - LiManObj.ApplicativoDTO answ = new LiManObj.ApplicativoDTO(); - // cerco da cache - string rawData = memLayer.ML.getRSV(rkeyLicInfo); - // se no ci fosse --> refresh online! - if (string.IsNullOrEmpty(rawData)) - { - var fatto = RefreshAppInfo().Result; - if (fatto) - { - rawData = memLayer.ML.getRSV(rkeyLicInfo); - } - } - if (!string.IsNullOrEmpty(rawData)) - { - try - { - // verifico se ho 1 risultato o molti...se inizia per "[" è molti - if (rawData.StartsWith("[")) - { - // POTREBBE darmi + di 1 risultato, prendo + recente... - List infoList = JsonConvert.DeserializeObject>(rawData); - if (infoList != null) - { - answ = infoList.OrderByDescending(x => x.Scadenza).FirstOrDefault(); - } - } - else - { - answ = JsonConvert.DeserializeObject(rawData); - } - } - catch - { } - } - return answ; - } - } + public static bool checkPayload => _checkPayload(); /// /// nome installazione sw /// - public static string installazione - { - get - { - string answ = ""; - try - { - answ = DataProxy.DP.taAKV.getByKey("installazione")[0].valString; - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore recupero chiave installazione da AKV: {0}", exc), tipoLog.EXCEPTION); - } - return answ; - } - } + public static string installazione => _installazione(); /// - /// numero di licenze attive sul sw (SE CONFORMI A CHIAVE) altrimenti da dll steamware + /// numero di licenze attive sul sw (SE CONFORMI A CHIAVE) /// - public static int licenzeAttive - { - get - { - int answ = 0; - int licenzeMax = licenseMan.getLicenseNum(installazione, applicazione); - // verifico dato su DB sia valido... expiry date con quel numero sia > della data odierna - if (scadenzaLicenza >= DateTime.Today) - { - answ = licenzeDb; - } - else - { - answ = licenzeMax; - } - return answ; - } - } + public static int licenzeAttive => _licenzeAttive(); /// /// numero di licenze attive su DB (NON verificate!) /// - public static int licenzeDb - { - get - { - int answ = 0; - // controllo su db... - try - { - answ = DataProxy.DP.taAKV.getByKey(installazione)[0].valInt; - } - catch - { } - return answ; - } - } + public static int licenzeDb => _licenzeDb(); /// /// numero di licenze disponibili da info online /// - public static int licenzeOnline - { - get - { - return InfoApplicativo.NumLicenze; - } - } + public static int licenzeOnline => _licenzeOnline(); /// /// Elenco attivazioni attuali /// - public static List ListaAttivazioni - { - get - { - List answ = new List(); - // cerco da cache - string rawData = memLayer.ML.getRSV(rkeyActInfo); - // se no ci fosse --> refresh online! - if (string.IsNullOrEmpty(rawData)) - { - var fatto = RefreshActInfo().Result; - if (fatto) - { - rawData = memLayer.ML.getRSV(rkeyActInfo); - } - } - if (!string.IsNullOrEmpty(rawData)) - { - answ = JsonConvert.DeserializeObject>(rawData); - } - return answ; - } - } + public static List ListaAttivazioni => _ListaAttivazioni(); /// - /// Chaive Licenza Master + /// Chiave Licenza Master /// - public static string MasterKey - { - get - { - string answ = ""; - try - { - answ = DataProxy.DP.taAKV.getByKey(installazione)[0].valString; - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore recupero chiave MasterKey da AKV: {0}", exc), tipoLog.EXCEPTION); - } - return answ; - } - } + public static string MasterKey => _MasterKey(); /// /// modalità applicazione (pagina test.aspx) /// - public static string modApp - { - get - { - string answ = ""; - try - { - answ = DataProxy.DP.taAKV.getByKey("appMode")[0].valString; - } - catch (Exception exc) - { - logger.lg.scriviLog(string.Format("Errore recupero chiave appMode da AKV: {0}", exc), tipoLog.EXCEPTION); - } - return answ; - } - } + public static string modApp => _modApp(); /// /// scadenza licenze x applicativo /// - public static DateTime scadenzaLicenza - { - get - { - DateTime answ = licenseMan.expiryDateByAuthKey(installazione, applicazione, DataProxy.DP.taAKV.getByKey(installazione)[0].valInt, DataProxy.DP.taAKV.getByKey(installazione)[0].valString); - return answ; - } - } + public static DateTime scadenzaLicenza => _scadenzaLicenza(); /// /// numero di utenti attivi /// - public static int utentiAttivi - { - get - { - int answ = DataProxy.DP.taDipendenti.getAttivi(false).Count; - return answ; - } - } + public static int utentiAttivi => _utentiAttivi(); #endregion Public Properties #region Private Methods - private static void tryCheckPayloadOnline(ref bool answ, ref string currPayload) + /// + /// numero di licenze attive da info online + /// + private static int _attivazioniOnline() { + return InfoApplicativo().NumLicenzeAttive; + } + + /// + /// chaive licenza + /// + private static string _authKey() + { + string answ = ""; + // controllo su db... try { - // cerco payload licenze locale... - currPayload = memLayer.ML.getRSV(rkeyPayload); - // se no ci fosse --> refresh online! - if (string.IsNullOrEmpty(currPayload)) - { - currPayload = calcPayload(); - memLayer.ML.setRSV(rkeyPayload, currPayload, LicCacheTTL); - } - // confronto payload calc con quello della licenza - answ = InfoApplicativo.Payload == currPayload; + answ = DataProxy.DP.taAKV.getByKey(installazione)[0].valString; } catch { } + return answ; } - #endregion Private Methods + /// + /// verifica se numero licenze copre utenti attivi... + /// + private static bool _checkLicenze() + { + bool answ = false; + try + { + // effettua refresh attivazioni... + var fatto = RefreshActInfo().Result; + answ = utentiAttivi <= licenzeAttive; + if (!answ && memLayer.ML.confReadInt("_logLevel") > 5) + { + logger.lg.scriviLog(string.Format("WARNING licenze: utenti attivi {0} / licenziati {1}", utentiAttivi, licenzeAttive), tipoLog.WARNING); + } + } + catch + { } + return answ; + } - #region Protected Methods + /// + /// verifica se il payload delle licenze attivate sia valido (con server online) + /// + private static bool _checkPayload() + { + bool answ = false; + string currPayload = ""; + tryCheckPayloadOnline(ref answ, ref currPayload); - protected static string calcPayload() + // se OK resetto counter, altrimenti incremento + if (!answ) + { + bool okRefreshPayload = string.IsNullOrEmpty(memLayer.ML.getRSV(rkeyVetoRefPayL)); + if (okRefreshPayload) + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + // richiedo update payload impostando TTL a 1 sec... + memLayer.ML.setRSV(rkeyPayload, "", 1); + var okApp = RefreshAppInfo().Result; + var okLic = RefreshActInfo().Result; + var okAct = RefreshLicInfo().Result; + var okPld = RefreshPayload().Result; + + // evito ricalcolo x 5 sec... + memLayer.ML.setRSV(rkeyVetoRefPayL, "Veto", 5); + sw.Stop(); + logger.lg.scriviLog($"Trovato payload non valido, effettuato reset variabili in {sw.ElapsedMilliseconds} ms"); + + sw.Start(); + tryCheckPayloadOnline(ref answ, ref currPayload); + sw.Stop(); + logger.lg.scriviLog($"Rivalutato payload con esito {answ} in {sw.ElapsedMilliseconds} ms"); + } + } + + return answ; + } + + /// + /// nome installazione sw + /// + private static string _installazione() + { + string answ = ""; + try + { + answ = DataProxy.DP.taAKV.getByKey("installazione")[0].valString; + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore recupero chiave installazione da AKV: {0}", exc), tipoLog.EXCEPTION); + } + return answ; + } + + /// + /// numero di licenze attive sul sw (SE CONFORMI A CHIAVE) + /// + private static int _licenzeAttive() + { + int answ = 0; + int licenzeMax = licenseMan.getLicenseNum(installazione, applicazione); + // verifico dato su DB sia valido... expiry date con quel numero sia > della data odierna + if (scadenzaLicenza >= DateTime.Today) + { + answ = licenzeDb; + } + else + { + answ = licenzeMax; + } + return answ; + } + + /// + /// numero di licenze attive su DB (NON verificate!) + /// + private static int _licenzeDb() + { + int answ = 0; + // controllo su db... + try + { + answ = DataProxy.DP.taAKV.getByKey(installazione)[0].valInt; + } + catch + { } + return answ; + } + + /// + /// numero di licenze disponibili da info online + /// + private static int _licenzeOnline() + { + return InfoApplicativo().NumLicenze; + } + + /// + /// Elenco attivazioni attuali + /// + private static List _ListaAttivazioni() + { + List answ = new List(); + // cerco da cache + string rawData = memLayer.ML.getRSV(rkeyActInfo); + // se no ci fosse --> refresh online! + if (string.IsNullOrEmpty(rawData)) + { + var fatto = RefreshActInfo().Result; + if (fatto) + { + rawData = memLayer.ML.getRSV(rkeyActInfo); + } + } + if (!string.IsNullOrEmpty(rawData)) + { + answ = JsonConvert.DeserializeObject>(rawData); + } + return answ; + } + + /// + /// Chiave Licenza Master + /// + private static string _MasterKey() + { + string answ = ""; + try + { + answ = DataProxy.DP.taAKV.getByKey(installazione)[0].valString; + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore recupero chiave MasterKey da AKV: {0}", exc), tipoLog.EXCEPTION); + } + return answ; + } + + /// + /// modalità applicazione (pagina test.aspx) + /// + private static string _modApp() + { + string answ = ""; + try + { + answ = DataProxy.DP.taAKV.getByKey("appMode")[0].valString; + } + catch (Exception exc) + { + logger.lg.scriviLog(string.Format("Errore recupero chiave appMode da AKV: {0}", exc), tipoLog.EXCEPTION); + } + return answ; + } + + /// + /// scadenza licenze x applicativo + /// + private static DateTime _scadenzaLicenza() + { + DateTime answ = licenseMan.expiryDateByAuthKey(installazione, applicazione, DataProxy.DP.taAKV.getByKey(installazione)[0].valInt, DataProxy.DP.taAKV.getByKey(installazione)[0].valString); + return answ; + } + + private static bool _userPayloadOk(int idxDip) + { + bool answ = false; + try + { + // recupero riga dip + var userTab = DataProxy.DP.taDipendenti.getByIdx(idxDip); + if (userTab != null && userTab.Count > 0) + { + var userRow = userTab[0]; + // calcolo suo codice... + var codImpCurr = DataProxy.DP.hashCodImpiego(userRow); + // cerco dip tra elenco json + var userLocalList = ListaAttivazioni; + var foundRec = userLocalList.Where(x => x.CodImpiego == codImpCurr); + answ = foundRec.Count() > 0; + } + } + catch + { } + + return answ; + } + + /// + /// numero di utenti attivi + /// + private static int _utentiAttivi() + { + int answ = DataProxy.DP.taDipendenti.getAttivi(false).Count; + return answ; + } + + /// + /// Calcolo Hash data stringa input + /// + /// + /// + private static string calcHash(string rawData) + { + string hash = ""; + // hashing! + using (var md5 = MD5.Create()) + { + byte[] InputBytes = Encoding.UTF8.GetBytes(rawData); + var byteHash = md5.ComputeHash(InputBytes); + hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant(); + } + return hash; + } + + private static string calcPayload() { string answ = ""; // costruisco stringa da elenco impieghi... @@ -428,28 +423,71 @@ namespace GPW_data return answ; } - #endregion Protected Methods + /// + /// Info applicativo corrente (da cache con eventuale recupero online...) + /// + private static LiManObj.ApplicativoDTO InfoApplicativo() + { + LiManObj.ApplicativoDTO answ = new LiManObj.ApplicativoDTO(); + // cerco da cache + string rawData = memLayer.ML.getRSV(rkeyLicInfo); + // se no ci fosse --> refresh online! + if (string.IsNullOrEmpty(rawData)) + { + var fatto = RefreshAppInfo().Result; + if (fatto) + { + rawData = memLayer.ML.getRSV(rkeyLicInfo); + } + } + if (!string.IsNullOrEmpty(rawData)) + { + try + { + // verifico se ho 1 risultato o molti...se inizia per "[" è molti + if (rawData.StartsWith("[")) + { + // POTREBBE darmi + di 1 risultato, prendo + recente... + List infoList = JsonConvert.DeserializeObject>(rawData); + if (infoList != null) + { + answ = infoList.OrderByDescending(x => x.Scadenza).FirstOrDefault(); + } + } + else + { + answ = JsonConvert.DeserializeObject(rawData); + } + } + catch + { } + } + return answ; + } + + private static void tryCheckPayloadOnline(ref bool answ, ref string currPayload) + { + try + { + // cerco payload licenze locale... + currPayload = memLayer.ML.getRSV(rkeyPayload); + // se no ci fosse --> refresh online! + if (string.IsNullOrEmpty(currPayload)) + { + currPayload = calcPayload(); + memLayer.ML.setRSV(rkeyPayload, currPayload, LicCacheTTL); + } + // confronto payload calc con quello della licenza + answ = InfoApplicativo().Payload == currPayload; + } + catch + { } + } + + #endregion Private Methods #region Public Methods - /// - /// Calcolo Hash data stringa input - /// - /// - /// - public static string calcHash(string rawData) - { - string hash = ""; - // hashing! - using (var md5 = MD5.Create()) - { - byte[] InputBytes = Encoding.UTF8.GetBytes(rawData); - var byteHash = md5.ComputeHash(InputBytes); - hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant(); - } - return hash; - } - /// /// Verifica attivazione licenza dato codice impiego /// @@ -741,29 +779,7 @@ namespace GPW_data return await Task.FromResult(answ); } - public static bool userPayloadOk(int idxDip) - { - bool answ = false; - try - { - // recupero riga dip - var userTab = DataProxy.DP.taDipendenti.getByIdx(idxDip); - if (userTab != null && userTab.Count > 0) - { - var userRow = userTab[0]; - // calcolo suo codice... - var codImpCurr = DataProxy.DP.hashCodImpiego(userRow); - // cerco dip tra elenco json - var userLocalList = ListaAttivazioni; - var foundRec = userLocalList.Where(x => x.CodImpiego == codImpCurr); - answ = foundRec.Count() > 0; - } - } - catch - { } - - return answ; - } + public static bool userPayloadOk(int idxDip) => _userPayloadOk(idxDip); #endregion Public Methods }