diff --git a/Core/Core.csproj b/Core/Core.csproj
index dbc1517..f208d30 100644
--- a/Core/Core.csproj
+++ b/Core/Core.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net5.0
diff --git a/Core/SampleStats.cs b/Core/SampleStats.cs
new file mode 100644
index 0000000..236b7e7
--- /dev/null
+++ b/Core/SampleStats.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Core
+{
+ public class SampleStats
+ {
+ public string Name { get; set; } = "NA";
+ public DateTime DtFirst { get; set; } = DateTime.Now;
+ public DateTime DtLast { get; set; } = DateTime.Now;
+ public List VList { get; set; } = new List();
+ }
+}
diff --git a/Core/SupportRequest.cs b/Core/SupportRequest.cs
index 1582ace..cab22a3 100644
--- a/Core/SupportRequest.cs
+++ b/Core/SupportRequest.cs
@@ -14,6 +14,7 @@ namespace Core
public string CodImp { get; set; } = "";
public string CodInst { get; set; } = "";
public string ContactEmail { get; set; } = "";
+ public string ContactName { get; set; } = "";
public string ContactPhone { get; set; } = "";
public int idxSubLic { get; set; } = 0;
diff --git a/LiMan.Api/Controllers/ApplicazioneController.cs b/LiMan.Api/Controllers/ApplicazioneController.cs
index fd1d71c..3d3c86e 100644
--- a/LiMan.Api/Controllers/ApplicazioneController.cs
+++ b/LiMan.Api/Controllers/ApplicazioneController.cs
@@ -33,7 +33,7 @@ namespace LiMan.APi.Controllers
///
public ApplicazioneController(ApiDataService DataService)
{
- _DataService = DataService;
+ dataService = DataService;
Log.Info("Avviata classe ApplicazioneController");
}
@@ -44,7 +44,7 @@ namespace LiMan.APi.Controllers
///
/// Dataservice x accesso DB
///
- protected ApiDataService _DataService { get; set; }
+ protected ApiDataService dataService { get; set; }
#endregion Protected Properties
@@ -60,7 +60,8 @@ namespace LiMan.APi.Controllers
[HttpGet("{id}")]
public async Task> Get(string id, string CodApp)
{
- var result = await _DataService.ApplicativiSearch(id, CodApp, true);
+ var result = await dataService.ApplicativiSearch(id, CodApp, true);
+ await dataService.recordCall(id, CodApp, $"GET:api/applicazione");
return result;
}
diff --git a/LiMan.Api/Controllers/AttivazioniController.cs b/LiMan.Api/Controllers/AttivazioniController.cs
index 124307f..a349357 100644
--- a/LiMan.Api/Controllers/AttivazioniController.cs
+++ b/LiMan.Api/Controllers/AttivazioniController.cs
@@ -34,7 +34,7 @@ namespace LiMan.APi.Controllers
///
public AttivazioniController(ApiDataService DataService)
{
- _DataService = DataService;
+ dataService = DataService;
Log.Info("Avviata classe AttivazioniController");
}
@@ -45,7 +45,7 @@ namespace LiMan.APi.Controllers
///
/// Dataservice x accesso DB
///
- protected ApiDataService _DataService { get; set; }
+ protected ApiDataService dataService { get; set; }
#endregion Protected Properties
@@ -58,7 +58,13 @@ namespace LiMan.APi.Controllers
[HttpDelete()]
public async Task Delete([FromBody] UserLicenseRequest CurrRequest)
{
- bool done = await _DataService.AttivazioniDelete(CurrRequest.MasterKey, CurrRequest.ParamDict);
+ bool done = await dataService.AttivazioniDelete(CurrRequest.MasterKey, CurrRequest.ParamDict);
+ // se ho qualcosa da loggare...
+ foreach (var item in CurrRequest.ParamDict)
+ {
+ // registro 1 riga x ogni record...
+ await dataService.recordCall(CurrRequest.MasterKey, $"DELETE:api/attivazioni:{item.Key}|{item.Value}");
+ }
return done;
}
@@ -72,8 +78,9 @@ namespace LiMan.APi.Controllers
public async Task> Get(string chiave)
{
List result = new List();
- var dbResult = await _DataService.AttivazioniByMasterKey(chiave, false);
+ var dbResult = await dataService.AttivazioniByMasterKey(chiave, false);
result = (dbResult != null) ? dbResult : result;
+ await dataService.recordCall(chiave, $"GET:api/attivazioni:{chiave}");
return result;
}
@@ -88,9 +95,14 @@ namespace LiMan.APi.Controllers
List currData = new List();
// eseguo tentativo generazione attivazioni da licenza...
- bool done = await _DataService.AttivazioniTryAdd(CurrRequest.MasterKey, CurrRequest.ParamDict, 60);
- currData = await _DataService.AttivazioniByMasterKey(CurrRequest.MasterKey, false);
-
+ bool done = await dataService.AttivazioniTryAdd(CurrRequest.MasterKey, CurrRequest.ParamDict, 60);
+ currData = await dataService.AttivazioniByMasterKey(CurrRequest.MasterKey, false);
+ // se ho qualcosa da loggare...
+ foreach (var item in CurrRequest.ParamDict)
+ {
+ // registro 1 riga x ogni record...
+ await dataService.recordCall(CurrRequest.MasterKey, $"POST:api/attivazioni:{item.Key}|{item.Value}");
+ }
return currData;
}
@@ -98,16 +110,21 @@ namespace LiMan.APi.Controllers
/// Richiesta di refresh delle key associate ai CodImpiego da una lista di chiavi di licenza sub
///
/// Obj Richiesta con licenza MASTER + Elenco codici impiego (key) + valori in formato dizionari
- // POST api/attivazioni
+ // POST api/attivazioni/refreshKey
[HttpPost("refreshKey")]
public async Task> refreshKey([FromBody] UserLicenseRequest CurrRequest)
{
List currData = new List();
// eseguo tentativo generazione attivazioni da licenza...
- bool done = await _DataService.AttivazioniTryRefresh(CurrRequest.MasterKey, CurrRequest.ParamDict);
- currData = await _DataService.AttivazioniByMasterKey(CurrRequest.MasterKey, false);
-
+ bool done = await dataService.AttivazioniTryRefresh(CurrRequest.MasterKey, CurrRequest.ParamDict);
+ currData = await dataService.AttivazioniByMasterKey(CurrRequest.MasterKey, false);
+ // se ho qualcosa da loggare...
+ foreach (var item in CurrRequest.ParamDict)
+ {
+ // registro 1 riga x ogni record...
+ await dataService.recordCall(CurrRequest.MasterKey, $"POST:api/attivazioni/refreshKey:{item.Key}__{item.Value}");
+ }
return currData;
}
@@ -115,11 +132,12 @@ namespace LiMan.APi.Controllers
/// Eliminazione di TUTTE le attivazioni SCADUTE
///
/// Licenza MASTER
- // DELETE api/attivazioni/5
+ // DELETE api/attivazioni/resetAvail
[HttpDelete("resetAvail")]
public async Task ResetAvail(string chiave)
{
- bool done = await _DataService.AttivazioniResetAvail(chiave);
+ bool done = await dataService.AttivazioniResetAvail(chiave);
+ await dataService.recordCall(chiave, $"DELETE:api/attivazioni/resetAvail:{chiave}");
return done;
}
@@ -127,27 +145,19 @@ namespace LiMan.APi.Controllers
/// Verifica recupero un record di sub licenza
///
/// Licenza MASTER
- /// Codice univoco impiego licenza
+ /// Codice univoco impiego licenza
///
// GET api/attivazioni/verifica/5
[HttpGet("verifica")]
- public async Task VerificaImpiego(string chiave, string CodImpiego)
+ public async Task VerificaImpiego(string chiave, string codImpiego)
{
DB.DTO.AttivazioneDTO result = new DB.DTO.AttivazioneDTO();
- var dbResult = await _DataService.AttivazioneSearch(chiave, CodImpiego, false);
+ var dbResult = await dataService.AttivazioneSearch(chiave, codImpiego, false);
result = (dbResult != null) ? dbResult : result;
+ await dataService.recordCall(chiave, $"GET:api/attivazioni/verifica:{chiave}__{codImpiego}");
return result;
}
#endregion Public Methods
-
-#if false
- // PUT api/attivazioni/5
- [HttpPut("{id}")]
- public void Put(int id, [FromBody] string value)
- {
- }
-
-#endif
}
}
\ No newline at end of file
diff --git a/LiMan.Api/Controllers/InstallazioniController.cs b/LiMan.Api/Controllers/InstallazioniController.cs
index 5cd7312..46c8c08 100644
--- a/LiMan.Api/Controllers/InstallazioniController.cs
+++ b/LiMan.Api/Controllers/InstallazioniController.cs
@@ -33,7 +33,7 @@ namespace LiMan.APi.Controllers
///
public InstallazioniController(ApiDataService DataService)
{
- _DataService = DataService;
+ dataService = DataService;
Log.Info("Avviata classe InstallazioniController");
}
@@ -44,7 +44,7 @@ namespace LiMan.APi.Controllers
///
/// Dataservice x accesso DB
///
- protected ApiDataService _DataService { get; set; }
+ protected ApiDataService dataService { get; set; }
#endregion Protected Properties
@@ -59,9 +59,9 @@ namespace LiMan.APi.Controllers
[HttpGet("{id}")]
public async Task> Get(string id)
{
- var result = await _DataService.LicenzeByCliente(id);
+ var result = await dataService.LicenzeByCliente(id);
var listaApp = result.Select(x => x.CodApp).ToList();
-
+ await dataService.recordCall(id, "*", "GET:api/installazioni");
return listaApp;
}
diff --git a/LiMan.Api/Controllers/LicenzaController.cs b/LiMan.Api/Controllers/LicenzaController.cs
index bb7ba4e..f86e8f6 100644
--- a/LiMan.Api/Controllers/LicenzaController.cs
+++ b/LiMan.Api/Controllers/LicenzaController.cs
@@ -34,7 +34,7 @@ namespace LiMan.APi.Controllers
///
public LicenzaController(ApiDataService DataService)
{
- _DataService = DataService;
+ dataService = DataService;
Log.Info("Avviata classe LicenzaController");
}
@@ -45,7 +45,7 @@ namespace LiMan.APi.Controllers
///
/// Dataservice x accesso DB
///
- protected ApiDataService _DataService { get; set; }
+ protected ApiDataService dataService { get; set; }
#endregion Protected Properties
@@ -62,8 +62,8 @@ namespace LiMan.APi.Controllers
[HttpGet("{id}")]
public async Task> Get(string id, string CodApp, string Chiave)
{
- var result = await _DataService.LicenzeSearch(id, CodApp, Chiave, false);
-
+ var result = await dataService.LicenzeSearch(id, CodApp, Chiave, false);
+ await dataService.recordCall(id, CodApp, $"GET:api/licenza:{Chiave}");
return result;
}
@@ -76,20 +76,21 @@ namespace LiMan.APi.Controllers
[HttpPost()]
public async Task> Get([FromBody] LicenseCoord AppInfo)
{
- var result = await _DataService.LicenzeSearch(AppInfo.CodInst, AppInfo.CodApp, AppInfo.MasterKey, false);
-
+ var result = await dataService.LicenzeSearch(AppInfo.CodInst, AppInfo.CodApp, AppInfo.MasterKey, false);
+ await dataService.recordCall(AppInfo.CodInst, AppInfo.CodApp, $"POST:api/licenza:{AppInfo.MasterKey}");
return result;
}
+ /// POST api/licenza/refreshPayload
///
/// Effettua refresh del payload calcolato ed aggiorna record ed infine lo restituisce
///
/// Info licenza in formato LicenseCoord
- // POST api/attivazioni/refreshPayload
[HttpPost("refreshPayload")]
public async Task RefreshPayload([FromBody] LicenseCoord AppInfo)
{
- var done = await _DataService.LicenzaRefreshPayload(AppInfo);
+ var done = await dataService.LicenzaRefreshPayload(AppInfo);
+ await dataService.recordCall(AppInfo.CodInst, AppInfo.CodApp, $"POST:api/licenza/refreshPayload:{AppInfo.MasterKey}");
return done;
}
diff --git a/LiMan.Api/Controllers/TicketController.cs b/LiMan.Api/Controllers/TicketController.cs
index aa50816..2c41eae 100644
--- a/LiMan.Api/Controllers/TicketController.cs
+++ b/LiMan.Api/Controllers/TicketController.cs
@@ -34,7 +34,7 @@ namespace LiMan.APi.Controllers
///
public TicketController(ApiDataService DataService)
{
- _DataService = DataService;
+ dataService = DataService;
Log.Info("Avviata classe TicketController");
}
@@ -45,7 +45,7 @@ namespace LiMan.APi.Controllers
///
/// Dataservice x accesso DB
///
- protected ApiDataService _DataService { get; set; }
+ protected ApiDataService dataService { get; set; }
#endregion Protected Properties
@@ -62,8 +62,8 @@ namespace LiMan.APi.Controllers
[HttpGet("{id}")]
public async Task> Get(string id, string CodApp, string Chiave)
{
- var result = await _DataService.TicketByCliente(id, CodApp, Chiave);
-
+ var result = await dataService.TicketByCliente(id, CodApp, Chiave);
+ await dataService.recordCall(id, CodApp, $"GET:api/ticket:{Chiave}");
return result;
}
@@ -80,11 +80,11 @@ namespace LiMan.APi.Controllers
if (CurrRequest.IsValid)
{
// registro richiesta
- var insRes = await _DataService.TicketAdd(CurrRequest);
+ var insRes = await dataService.TicketAdd(CurrRequest);
}
// restituisco richieste aperte
- result = await _DataService.TicketByCliente(CurrRequest.CodInst, CurrRequest.CodApp, CurrRequest.MasterKey);
-
+ result = await dataService.TicketByCliente(CurrRequest.CodInst, CurrRequest.CodApp, CurrRequest.MasterKey);
+ await dataService.recordCall(CurrRequest.CodInst, CurrRequest.CodApp, $"POST:api/ticket/sendReq:{CurrRequest.MasterKey}");
return result;
}
diff --git a/LiMan.Api/Data/ApiDataService.cs b/LiMan.Api/Data/ApiDataService.cs
index 05274d4..24278a7 100644
--- a/LiMan.Api/Data/ApiDataService.cs
+++ b/LiMan.Api/Data/ApiDataService.cs
@@ -1,13 +1,19 @@
using Core;
+using LiMan.DB.DBModels;
+using Microsoft.AspNetCore.Identity.UI.Services;
+using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Text;
using System.Threading.Tasks;
using static LiMan.DB.Enum;
+using StackExchange.Redis.Extensions.Core.Abstractions;
namespace LiMan.APi.Data
{
@@ -16,21 +22,57 @@ namespace LiMan.APi.Data
///
public class ApiDataService : IDisposable
{
+ #region Public Fields
+
+ ///
+ /// Classe Accesso metodi DB
+ ///
+ public static LiMan.DB.Controllers.DbController dbController;
+
+ #endregion Public Fields
+
+ #region Protected Fields
+
+ ///
+ /// TTL da 1 h x cache Redis
+ ///
+ protected const int hourTTL = 60 * 60;
+
+ ///
+ /// Chiave redis x statistiche in acquisizione
+ ///
+ protected const string rKeySampleStats = "LiMan.UI:SampleStats:Curr";
+
+ ///
+ /// Chiave redis x statistiche in acquisizione
+ ///
+ protected const string rKeySampleVars = "LiMan.UI:SampleStats:Vars";
+
+ #endregion Protected Fields
+
#region Private Fields
private static IConfiguration _configuration;
private static ILogger _logger;
-
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+ private readonly IEmailSender _emailSender;
+
+ //private readonly IDistributedCache distributedCache;
+ private readonly IRedisCacheClient _redisCacheClient;
+
+ ///
+ /// Durata assoluta massima della cache IN SECONDI
+ ///
+ private int chAbsExp = 60 * 5;
+
+ ///
+ /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa
+ /// NON estende oltre il tempo massimo di validità della cache (chAbsExp)
+ ///
+ private int chSliExp = 60 * 2;
#endregion Private Fields
- #region Public Fields
-
- public static LiMan.DB.Controllers.DbController dbController;
-
- #endregion Public Fields
-
#region Public Constructors
///
@@ -38,10 +80,18 @@ namespace LiMan.APi.Data
///
///
///
- public ApiDataService(IConfiguration configuration, ILogger logger)
+ ///
+ ///
+ ///
+ public ApiDataService(IConfiguration configuration, ILogger logger, IEmailSender emailSender, IRedisCacheClient redisCacheClient)
+ //public ApiDataService(IConfiguration configuration, ILogger logger, IDistributedCache distributedCache, IEmailSender emailSender, IRedisCacheClient redisCacheClient)
{
_logger = logger;
_configuration = configuration;
+ _emailSender = emailSender;
+ _redisCacheClient = redisCacheClient;
+ //this.distributedCache = distributedCache;
+
// conf DB
string connStrDB = _configuration.GetConnectionString("LiMan.DB");
if (string.IsNullOrEmpty(connStrDB))
@@ -57,24 +107,6 @@ namespace LiMan.APi.Data
#endregion Public Constructors
- #region Internal Methods
-
- ///
- /// Effettua refresh del payload della licenza dato info + enigma generato dal client
- ///
- ///
- ///
- internal async Task LicenzaRefreshPayload(LicenseCoord appInfo)
- {
- // chiamo metodo x ricalcolare payload dato enigma
- bool done = await dbController.LicenseUpdatePayload(appInfo.CodInst, appInfo.CodApp, appInfo.MasterKey, appInfo.Enigma);
- // ora recupero i dati
- var licList = await LicenzeSearch(appInfo.CodInst, appInfo.CodApp, appInfo.MasterKey, false);
- return licList.FirstOrDefault();
- }
-
- #endregion Internal Methods
-
#region Public Methods
///
@@ -269,6 +301,71 @@ namespace LiMan.APi.Data
dbController.Dispose();
}
+ ///
+ /// Elenco licenze dato cliente
+ ///
+ /// Chiave Licenza x ricerca
+ ///
+ public async Task LicenzaByMasterKey(string chiave)
+ {
+ LicenzaModel dbResult = new LicenzaModel();
+ string cacheKey = $"DATA:Licenze:ListByKey:{chiave}";
+#if false
+ string rawData;
+ var redisDataList = await distributedCache.GetAsync(cacheKey);
+ if (redisDataList != null)
+ {
+ rawData = Encoding.UTF8.GetString(redisDataList);
+ dbResult = JsonConvert.DeserializeObject(rawData);
+ }
+ else
+ {
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+ dbResult = dbController.LicenzaByKey(chiave);
+ rawData = JsonConvert.SerializeObject(dbResult);
+ redisDataList = Encoding.UTF8.GetBytes(rawData);
+ await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(5));
+ stopWatch.Stop();
+ TimeSpan ts = stopWatch.Elapsed;
+ Log.Trace($"Effettuata lettura da DB per LicenzaByMasterKey: {ts.TotalMilliseconds} ms");
+ }
+#endif
+
+ string rawData = await getRSV(cacheKey);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ dbResult = JsonConvert.DeserializeObject(rawData);
+ }
+ else
+ {
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+ dbResult = dbController.LicenzaByKey(chiave);
+ rawData = JsonConvert.SerializeObject(dbResult);
+ await setRSV(cacheKey, rawData, hourTTL);
+ stopWatch.Stop();
+ TimeSpan ts = stopWatch.Elapsed;
+ Log.Trace($"Effettuata lettura da DB per LicenzaByMasterKey: {ts.TotalMilliseconds} ms");
+ }
+
+ return await Task.FromResult(dbResult);
+ }
+
+ ///
+ /// Effettua refresh del payload della licenza dato info + enigma generato dal client
+ ///
+ ///
+ ///
+ public async Task LicenzaRefreshPayload(LicenseCoord appInfo)
+ {
+ // chiamo metodo x ricalcolare payload dato enigma
+ bool done = await dbController.LicenseUpdatePayload(appInfo.CodInst, appInfo.CodApp, appInfo.MasterKey, appInfo.Enigma);
+ // ora recupero i dati
+ var licList = await LicenzeSearch(appInfo.CodInst, appInfo.CodApp, appInfo.MasterKey, false);
+ return licList.FirstOrDefault();
+ }
+
///
/// Elenco licenze dato cliente
///
@@ -310,6 +407,101 @@ namespace LiMan.APi.Data
return await Task.FromResult(dbResult);
}
+ ///
+ /// Effettua registrazione chiamata verificando se vada messa sul DB o in redis...
+ ///
+ ///
+ ///
+ ///
+ public async Task recordCall(string codInst, string codApp, string targetUrl)
+ {
+ bool fatto = false;
+
+ // in primis recupero statistiche (e nel mentre eventualmente salvo su DB)
+ SampleStats currStats = await getCurrStats();
+
+ // preparo chiave x dato da loggare
+ string currKey = $"{rKeySampleVars}:{codInst}:{codApp}:{targetUrl}";
+
+ // verifico presenza contatore corrente altrimenti aggiungo e salvo...
+ if (!currStats.VList.Contains(currKey))
+ {
+ currStats.VList.Add(currKey);
+ // salvo!
+ await setCurrStats(currStats);
+ }
+ // incremento valore contatore corrente
+ await redCountIncr(currKey);
+
+ return fatto;
+ }
+
+ ///
+ /// Effettua registrazione da codice chiave...
+ ///
+ ///
+ ///
+ public async Task recordCall(string chiave, string targetUrl)
+ {
+ // valutare se cache key --> lic...
+ var currLic = await LicenzaByMasterKey(chiave);
+ var fatto = await recordCall(currLic.CodInst, currLic.CodApp, targetUrl);
+ return fatto;
+ }
+
+ ///
+ /// Registro su DB le statistiche delle chiavi in elenco, resettando i vari contatori quando fatto
+ ///
+ /// Elenco key nel formato {rKeySampleVars}:{codInst}:{codApp}:{targetUrl}
+ public async Task saveStatsToDb(List keyList)
+ {
+ bool fatto = false;
+ // ciclo x eseguire 1:1
+ foreach (var item in keyList)
+ {
+ // scompongo key... senza url di base
+ string[] valStr = item.Replace($"{rKeySampleVars}:", "").Split(":");
+ if (valStr.Length > 2)
+ {
+ LogCallModel newRec = new LogCallModel()
+ {
+ CodInst = valStr[0],
+ CodApp = valStr[1],
+ TargetUrl = valStr[2],
+ DataRif = DateTime.Now,
+ NumCall = 1
+ };
+ fatto = await dbController.LogCallUpsert(newRec);
+ if (fatto)
+ {
+ await redCountClear(item);
+ }
+ }
+ }
+ return fatto;
+ }
+
+ ///
+ /// Invio email richiesta
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendEmail(string destEmail, string oggetto, string corpo)
+ {
+ bool answ = false;
+ try
+ {
+ await _emailSender.SendEmailAsync(destEmail, oggetto, corpo);
+ answ = true;
+ }
+ catch
+ { }
+
+ return answ;
+ }
+
///
/// Esegue aggiunta Ticket richeisto + restitusice aperti x cliente
///
@@ -376,6 +568,147 @@ namespace LiMan.APi.Data
#endregion Public Methods
+ #region Protected Methods
+
+ ///
+ /// Recupera statistiche correnti
+ ///
+ ///
+ protected async Task getCurrStats()
+ {
+ DateTime adesso = DateTime.Now;
+ SampleStats answ = new SampleStats()
+ {
+ Name = "ApiStats"
+ };
+ // in primis check data/ora prima/ultima scrittura del set... (2 date, lista chiavi gestite)
+ string rawData = await getRSV(rKeySampleStats);
+ if (rawData != null)
+ {
+ answ = JsonConvert.DeserializeObject(rawData);
+ // aggiorno ultimo controllo e salvo...
+ answ.DtLast = adesso;
+ // salvo!
+ await setCurrStats(answ);
+ }
+ // controllo se scadute...
+ if (adesso.Subtract(answ.DtFirst).TotalMinutes > 60)
+ {
+ // se scaduto --> registrazione set sul DB (async), resettando i vari contatori...
+ bool salvato = await saveStatsToDb(answ.VList);
+ // inizio NUOVO set vuoto con record corrente
+ answ = new SampleStats()
+ {
+ Name = "ApiStats"
+ };
+ // salvo!
+ await setCurrStats(answ);
+ }
+ // restituisco record!
+ return answ;
+ }
+
+ ///
+ /// Recupero chiave da redis
+ ///
+ ///
+ ///
+ protected async Task getRSV(string rKey)
+ {
+ string answ = await _redisCacheClient.GetDbFromConfiguration().GetAsync(rKey);
+ return answ;
+ }
+
+ ///
+ /// Resetta contatore x la chiave redis indicata...
+ ///
+ ///
+ protected async Task redCountClear(string rKey)
+ {
+ bool answ = false;
+ int currCount = 0;
+ answ = await setRSV(rKey, currCount, 2 * hourTTL);
+ return answ;
+ }
+
+ ///
+ /// Incrementa contatore x la chiave redis indicata...
+ ///
+ ///
+ protected async Task redCountIncr(string rKey)
+ {
+ bool answ = false;
+ int currCount = 0;
+ string rawVal = await getRSV(rKey);
+ if (!string.IsNullOrEmpty(rawVal))
+ {
+ int.TryParse(rawVal, out currCount);
+ }
+ currCount++;
+ answ = await setRSV(rKey, currCount, 2 * hourTTL);
+ return answ;
+ }
+
+ ///
+ /// Salva statistiche correnti
+ ///
+ ///
+ protected async Task setCurrStats(SampleStats newVal)
+ {
+ bool answ = false;
+ string rawData = JsonConvert.SerializeObject(newVal);
+ answ = await setRSV(rKeySampleStats, rawData, 24 * hourTTL);
+ return answ;
+ }
+
+ ///
+ /// Salvataggio chiave in redis
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected async Task setRSV(string rKey, string rVal, int ttlSec)
+ {
+ bool fatto = false;
+ await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rVal, DateTimeOffset.Now.AddSeconds(ttlSec));
+ fatto = true;
+ return fatto;
+ }
+
+ ///
+ /// Salvataggio chiave in redis
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected async Task setRSV(string rKey, int rValInt, int ttlSec)
+ {
+ bool fatto = false;
+ await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rValInt, DateTimeOffset.Now.AddSeconds(ttlSec));
+ fatto = true;
+ return fatto;
+ }
+
+ #endregion Protected Methods
+
+ #region Private Methods
+
+ ///
+ /// Parametri per generare opzioni cache
+ ///
+ /// Fattore di moltiplica cache (se 1 --> 2 e 5 min)
+ ///
+ private DistributedCacheEntryOptions cacheOpt(int multFact)
+ {
+ var numSecAbsExp = multFact <= 0 ? chAbsExp : chAbsExp * multFact;
+ var numSecSliExp = multFact <= 0 ? chSliExp : chSliExp * multFact;
+ return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
+ }
+
+ #endregion Private Methods
+
#if false
///
/// Elenco ticket dato licenza (limitato a maxRec)
diff --git a/LiMan.Api/LiMan.APi.csproj b/LiMan.Api/LiMan.APi.csproj
index 08c163a..61666c4 100644
--- a/LiMan.Api/LiMan.APi.csproj
+++ b/LiMan.Api/LiMan.APi.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net5.0
@@ -16,8 +16,12 @@
+
+
+
+
diff --git a/LiMan.Api/LiMan.APi.xml b/LiMan.Api/LiMan.APi.xml
index 52caca2..024eacb 100644
--- a/LiMan.Api/LiMan.APi.xml
+++ b/LiMan.Api/LiMan.APi.xml
@@ -20,7 +20,7 @@
-
+
Dataservice x accesso DB
@@ -50,7 +50,7 @@
-
+
Dataservice x accesso DB
@@ -90,7 +90,7 @@
Verifica recupero un record di sub licenza
Licenza MASTER
- Codice univoco impiego licenza
+ Codice univoco impiego licenza
@@ -109,7 +109,7 @@
-
+
Dataservice x accesso DB
@@ -138,7 +138,7 @@
-
+
Dataservice x accesso DB
@@ -162,6 +162,7 @@
+ POST api/licenza/refreshPayload
Effettua refresh del payload calcolato ed aggiorna record ed infine lo restituisce
@@ -183,7 +184,7 @@
-
+
Dataservice x accesso DB
@@ -209,18 +210,62 @@
Classe astrazione accesso dati
-
+
+
+ Durata assoluta massima della cache IN SECONDI
+
+
+
+
+ Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa
+ NON estende oltre il tempo massimo di validità della cache (chAbsExp)
+
+
+
+
+ Classe Accesso metodi DB
+
+
+
+
+ Recupero chiave da redis
+
+
+
+
+
+
+ Salvataggio chiave in redis
+
+
+
+
+
+
+
+
+ Salvataggio chiave in redis
+
+
+
+
+
+
+
Init classe
+
+
+
-
+
- Effettua refresh del payload della licenza dato info + enigma generato dal client
+ Parametri per generare opzioni cache
-
+ Fattore di moltiplica cache (se 1 --> 2 e 5 min)
@@ -296,6 +341,20 @@
Dispose classe
+
+
+ Elenco licenze dato cliente
+
+ Chiave Licenza x ricerca
+
+
+
+
+ Effettua refresh del payload della licenza dato info + enigma generato dal client
+
+
+
+
Elenco licenze dato cliente
@@ -313,6 +372,75 @@
Indica se nascondere i dati sensibili
+
+
+ Chiave redis x statistiche in acquisizione
+
+
+
+
+ Chiave redis x statistiche in acquisizione
+
+
+
+
+ Recupera statistiche correnti
+
+
+
+
+
+ TTL da 1 h x cache Redis
+
+
+
+
+ Salva statistiche correnti
+
+
+
+
+
+ Incrementa contatore x la chiave redis indicata...
+
+
+
+
+
+ Resetta contatore x la chiave redis indicata...
+
+
+
+
+
+ Effettua registrazione chiamata verificando se vada messa sul DB o in redis...
+
+
+
+
+
+
+
+ Registro su DB le statistiche delle chiavi in elenco, resettando i vari contatori quando fatto
+
+ Elenco key nel formato {rKeySampleVars}:{codInst}:{codApp}:{targetUrl}
+
+
+
+ Effettua registrazione da codice chiave...
+
+
+
+
+
+
+ Invio email richiesta
+
+
+
+
+
+
Esegue aggiunta Ticket richeisto + restitusice aperti x cliente
diff --git a/LiMan.Api/Properties/PublishProfiles/IIS01.pubxml b/LiMan.Api/Properties/PublishProfiles/IIS01.pubxml
index 74819e0..187f479 100644
--- a/LiMan.Api/Properties/PublishProfiles/IIS01.pubxml
+++ b/LiMan.Api/Properties/PublishProfiles/IIS01.pubxml
@@ -23,6 +23,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
True
jenkins
<_SavePWD>True
- net6.0
+ net5.0
\ No newline at end of file
diff --git a/LiMan.Api/Properties/PublishProfiles/IIS02.pubxml b/LiMan.Api/Properties/PublishProfiles/IIS02.pubxml
index c5c0433..6f49e68 100644
--- a/LiMan.Api/Properties/PublishProfiles/IIS02.pubxml
+++ b/LiMan.Api/Properties/PublishProfiles/IIS02.pubxml
@@ -23,6 +23,6 @@ by editing this MSBuild file. In order to learn more about this please visit htt
True
jenkins
<_SavePWD>True
- net6.0
+ net5.0
\ No newline at end of file
diff --git a/LiMan.Api/Properties/PublishProfiles/W2019-IIS-DEV.pubxml b/LiMan.Api/Properties/PublishProfiles/W2019-IIS-DEV.pubxml
index c60784c..25b5587 100644
--- a/LiMan.Api/Properties/PublishProfiles/W2019-IIS-DEV.pubxml
+++ b/LiMan.Api/Properties/PublishProfiles/W2019-IIS-DEV.pubxml
@@ -22,7 +22,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
True
jenkins
<_SavePWD>True
- net6.0
+ net5.0
false
\ No newline at end of file
diff --git a/LiMan.Api/Startup.cs b/LiMan.Api/Startup.cs
index 495c66b..02b0fdd 100644
--- a/LiMan.Api/Startup.cs
+++ b/LiMan.Api/Startup.cs
@@ -1,19 +1,17 @@
using LiMan.APi.Data;
+using LiMan.DB;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.HttpsPolicy;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
+using StackExchange.Redis.Extensions.Core.Configuration;
+using StackExchange.Redis.Extensions.Newtonsoft;
using System;
-using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Reflection;
-using System.Threading.Tasks;
namespace LiMan.Serv
{
@@ -77,6 +75,28 @@ namespace LiMan.Serv
c.IncludeXmlComments(xmlPath);
});
+ // abilitazione x email management con MailKit
+ services.AddTransient();
+ services.Configure(options =>
+ {
+ options.Host_Address = Configuration["ExternalProviders:MailKit:SMTP:Address"];
+ options.Host_Port = Convert.ToInt32(Configuration["ExternalProviders:MailKit:SMTP:Port"]);
+ options.Host_Username = Configuration["ExternalProviders:MailKit:SMTP:Account"];
+ options.Host_Password = Configuration["ExternalProviders:MailKit:SMTP:Password"];
+ options.Sender_EMail = Configuration["ExternalProviders:MailKit:SMTP:SenderEmail"];
+ options.Sender_Name = Configuration["ExternalProviders:MailKit:SMTP:SenderName"];
+ });
+
+ //services.AddStackExchangeRedisCache(options =>
+ //{
+ // options.Configuration = Configuration.GetConnectionString("Redis");
+ //});
+
+ services.AddStackExchangeRedisExtensions((options) =>
+ {
+ return Configuration.GetSection("Redis").Get();
+ });
+
services.AddSingleton();
}
diff --git a/LiMan.Api/appsettings.json b/LiMan.Api/appsettings.json
index 51ed134..77041ab 100644
--- a/LiMan.Api/appsettings.json
+++ b/LiMan.Api/appsettings.json
@@ -1,15 +1,45 @@
{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "AllowedHosts": "*",
- "ConnectionStrings": {
- "LiMan.GLS": "Server=SQLSTEAM;Database=SteamWare_Auth;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.API;",
- "LiMan.DB": "Server=SQLSTEAM;Database=LiMan.DB;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.API;",
- "Redis": "localhost:6379"
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
}
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "LiMan.GLS": "Server=SQLSTEAM;Database=SteamWare_Auth;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.API;",
+ "LiMan.DB": "Server=SQLSTEAM;Database=LiMan.DB;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.API;",
+ "Redis": "localhost:6379,DefaultDatabase=13"
+ },
+ "ExternalProviders": {
+ "MailKit": {
+ "SMTP": {
+ "Address": "smtp.gmail.com",
+ "Port": "465",
+ "Account": "steamwarebot@gmail.com",
+ "Password": "drmfsls16",
+ "SenderEmail": "steamwarebot@gmail.com",
+ "SenderName": "Steamware Email BOT"
+ }
+ }
+ },
+ "MailDest": {
+ "Admin": "samuele@steamware.net",
+ "ProcOp": "ceo@steamware.net"
+ },
+ "Redis": {
+ "Password": "",
+ "AllowAdmin": false,
+ "Ssl": false,
+ "ConnectTimeout": 6000,
+ "ConnectRetry": 2,
+ "Hosts": [
+ {
+ "Host": "localhost",
+ "Port": "6379"
+ }
+ ],
+ "Database": 14
+ }
}
\ No newline at end of file
diff --git a/LiMan.DB/Controllers/DbController.cs b/LiMan.DB/Controllers/DbController.cs
index 63b7e2c..d108ec5 100644
--- a/LiMan.DB/Controllers/DbController.cs
+++ b/LiMan.DB/Controllers/DbController.cs
@@ -53,7 +53,7 @@ namespace LiMan.DB.Controllers
// calcolo DTO Attivazione
var itemsTgt = localDbCtx
.DbSetSubLicenze
- .Where(x => x.CodImpiego == item.Key && x.Chiave == item.Value && x.LicenzaNav.Chiave == MasterKey && x.VetoUnlock < oggi)
+ .Where(x => x.CodImpiego == item.Key && x.Chiave == item.Value && x.LicenzaNav.Chiave == MasterKey && x.VetoUnlock <= oggi)
.ToList();
// se trovate aggiungo ad elenco...
if (itemsTgt != null && itemsTgt.Count > 0)
@@ -653,6 +653,80 @@ namespace LiMan.DB.Controllers
return Task.FromResult(fatto);
}
+ public LicenzaModel LicenzaByKey(string MasterKey)
+ {
+ LicenzaModel dbResult = new LicenzaModel();
+ using (LMDbContext localDbCtx = new LMDbContext(_configuration))
+ {
+ DateTime oggi = DateTime.Today;
+ dbResult = localDbCtx
+ .DbSetLicenze
+ .Where(x => x.Chiave == MasterKey)
+ .FirstOrDefault();
+ }
+ return dbResult;
+ }
+
+ ///
+ /// Elenco LOG chiamate all'API dato filtro + limite record
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public List LogCallGetFilt(string CodApp, string CodInst, DateTime DateMax, int maxNumRec = 360)
+ {
+ List dbResult = new List();
+ using (LMDbContext localDbCtx = new LMDbContext(_configuration))
+ {
+ // recupero lista...
+ dbResult = localDbCtx
+ .DbSetLogCall
+ .Where(x => x.CodApp == CodApp && x.CodInst == CodInst && x.DataRif <= DateMax)
+ .OrderByDescending(x => x.DataRif)
+ .Take(maxNumRec)
+ .ToList();
+ }
+ return dbResult;
+ }
+
+ ///
+ /// Update/insert record Loc chiamate API
+ ///
+ ///
+ ///
+ public async Task LogCallUpsert(LogCallModel currRequest)
+ {
+ bool fatto = false;
+ using (LMDbContext localDbCtx = new LMDbContext(_configuration))
+ {
+ // cerco record esistente...
+ var currRec = localDbCtx
+ .DbSetLogCall
+ .Where(x => x.CodApp == currRequest.CodApp && x.CodInst == currRequest.CodInst && x.DataRif == currRequest.DataRif && x.TargetUrl == currRequest.TargetUrl)
+ .FirstOrDefault();
+ if (currRec != null)
+ {
+ // se trovo aggiorno
+ currRec.NumCall = currRequest.NumCall;
+ }
+ else
+ {
+ //altrimenti aggiungo
+ localDbCtx
+ .DbSetLogCall
+ .Add(currRequest);
+ }
+
+ // salvo
+ await localDbCtx.SaveChangesAsync();
+
+ fatto = true;
+ }
+ return fatto;
+ }
+
///
/// Annulla modifiche su una specifica entity (cancel update)
///
diff --git a/LiMan.DB/DBModels/LogCallModel.cs b/LiMan.DB/DBModels/LogCallModel.cs
new file mode 100644
index 0000000..cbc751d
--- /dev/null
+++ b/LiMan.DB/DBModels/LogCallModel.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using static LiMan.DB.Enum;
+
+#nullable disable
+
+namespace LiMan.DB.DBModels
+{
+ //
+ // This is here so CodeMaid doesn't reorganize this document
+ //
+ //[Index(nameof(Installazione), nameof(Active), nameof(DiskStatus))]
+ [Table("LogCall")]
+ public partial class LogCallModel
+ {
+ #region Public Properties
+
+ public DateTime DataRif { get; set; }
+ public string CodInst { get; set; }
+ public string CodApp { get; set; }
+ public string TargetUrl { get; set; }
+ public int NumCall { get; set; } = 0;
+
+
+ #endregion Public Properties
+ }
+}
\ No newline at end of file
diff --git a/LiMan.DB/LMDbContext.cs b/LiMan.DB/LMDbContext.cs
index 15d535c..27a1305 100644
--- a/LiMan.DB/LMDbContext.cs
+++ b/LiMan.DB/LMDbContext.cs
@@ -49,23 +49,17 @@ namespace LiMan.DB
#region Public Properties
public virtual DbSet DbSetApp { get; set; }
-
public virtual DbSet DbSetInst { get; set; }
-
public virtual DbSet DbSetLicenze { get; set; }
-
+ public virtual DbSet DbSetLogCall { get; set; }
public virtual DbSet DbSetLogLicenze { get; set; }
public virtual DbSet DbSetSubLicenze { get; set; }
-
public virtual DbSet DbSetTicket { get; set; }
#endregion Public Properties
-
- #region Private Methods
-
+
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
- #endregion Private Methods
#region Protected Methods
@@ -89,6 +83,11 @@ namespace LiMan.DB
{
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => new { e.DataRif, e.CodInst, e.CodApp, e.TargetUrl });
+ });
+
OnModelCreatingPartial(modelBuilder);
}
diff --git a/LiMan.DB/LiMan.DB.csproj b/LiMan.DB/LiMan.DB.csproj
index fb5bd7e..dae6bfc 100644
--- a/LiMan.DB/LiMan.DB.csproj
+++ b/LiMan.DB/LiMan.DB.csproj
@@ -1,14 +1,13 @@
- net6.0
+ net5.0
-
-
-
-
+
+
+
diff --git a/LiMan.DB/MailKitEmailSender.cs b/LiMan.DB/MailKitEmailSender.cs
new file mode 100644
index 0000000..53cdba5
--- /dev/null
+++ b/LiMan.DB/MailKitEmailSender.cs
@@ -0,0 +1,65 @@
+using MailKit.Net.Smtp;
+using Microsoft.AspNetCore.Identity.UI.Services;
+using Microsoft.Extensions.Options;
+using MimeKit;
+using MimeKit.Text;
+using System.Threading.Tasks;
+
+namespace LiMan.DB
+{
+ ///
+ /// Implementazione interfaccia email con pacchetto MailKIT
+ ///
+ /// https://www.ryadel.com/en/asp-net-core-send-email-messages-smtp-mailkit/
+ ///
+ public class MailKitEmailSender : IEmailSender
+ {
+ #region Public Constructors
+
+ public MailKitEmailSender(IOptions options)
+ {
+ this.Options = options.Value;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ public MailKitEmailSenderOptions Options { get; set; }
+
+ #endregion Public Properties
+
+ #region Public Methods
+
+ public Task Execute(string to, string subject, string message)
+ {
+ // create message
+ var email = new MimeMessage();
+ email.Sender = MailboxAddress.Parse(Options.Sender_EMail);
+ if (!string.IsNullOrEmpty(Options.Sender_Name))
+ email.Sender.Name = Options.Sender_Name;
+ email.From.Add(email.Sender);
+ email.To.Add(MailboxAddress.Parse(to));
+ email.Subject = subject;
+ email.Body = new TextPart(TextFormat.Html) { Text = message };
+
+ // send email
+ using (var smtp = new SmtpClient())
+ {
+ smtp.Connect(Options.Host_Address, Options.Host_Port, Options.Host_SecureSocketOptions);
+ smtp.Authenticate(Options.Host_Username, Options.Host_Password);
+ smtp.Send(email);
+ smtp.Disconnect(true);
+ }
+
+ return Task.FromResult(true);
+ }
+
+ public Task SendEmailAsync(string email, string subject, string message)
+ {
+ return Execute(email, subject, message);
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/LiMan.DB/MailKitEmailSenderOptions.cs b/LiMan.DB/MailKitEmailSenderOptions.cs
new file mode 100644
index 0000000..43de307
--- /dev/null
+++ b/LiMan.DB/MailKitEmailSenderOptions.cs
@@ -0,0 +1,36 @@
+using MailKit.Security;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LiMan.DB
+{
+ public class MailKitEmailSenderOptions
+ {
+ #region Public Constructors
+
+ public MailKitEmailSenderOptions()
+ {
+ Host_SecureSocketOptions = SecureSocketOptions.Auto;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ public string Host_Address { get; set; }
+
+ public string Host_Password { get; set; }
+ public int Host_Port { get; set; }
+
+ public SecureSocketOptions Host_SecureSocketOptions { get; set; }
+ public string Host_Username { get; set; }
+ public string Sender_EMail { get; set; }
+
+ public string Sender_Name { get; set; }
+
+ #endregion Public Properties
+ }
+}
\ No newline at end of file
diff --git a/LiMan.DB/Migrations/20211117101539_AddLogCalls.Designer.cs b/LiMan.DB/Migrations/20211117101539_AddLogCalls.Designer.cs
new file mode 100644
index 0000000..d107d63
--- /dev/null
+++ b/LiMan.DB/Migrations/20211117101539_AddLogCalls.Designer.cs
@@ -0,0 +1,331 @@
+//
+using System;
+using LiMan.DB;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace LiMan.DB.Migrations
+{
+ [DbContext(typeof(LMDbContext))]
+ [Migration("20211117101539_AddLogCalls")]
+ partial class AddLogCalls
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("ProductVersion", "5.0.10")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("LiMan.DB.DBModels.ApplicativoModel", b =>
+ {
+ b.Property("CodApp")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Descrizione")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.HasKey("CodApp");
+
+ b.ToTable("Applicativi");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.InstallazioneModel", b =>
+ {
+ b.Property("CodInst")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Cliente")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.Property("Contatto")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.Property("Descrizione")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.Property("Email")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.HasKey("CodInst");
+
+ b.ToTable("Installazioni");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
+ {
+ b.Property("IdxLic")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("Chiave")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CodApp")
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("CodInst")
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("DataEnigma")
+ .HasColumnType("datetime2");
+
+ b.Property("Descrizione")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Enigma")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Locked")
+ .HasColumnType("bit");
+
+ b.Property("NumLicenze")
+ .HasColumnType("int");
+
+ b.Property("Payload")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Scadenza")
+ .HasColumnType("datetime2");
+
+ b.Property("Tipo")
+ .HasColumnType("int");
+
+ b.HasKey("IdxLic");
+
+ b.HasIndex("CodApp");
+
+ b.HasIndex("CodInst");
+
+ b.ToTable("Licenze");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.LogCallModel", b =>
+ {
+ b.Property("DataRif")
+ .HasColumnType("datetime2");
+
+ b.Property("CodInst")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("CodApp")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("TargetUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("NumCall")
+ .HasColumnType("int");
+
+ b.HasKey("DataRif", "CodInst", "CodApp", "TargetUrl");
+
+ b.ToTable("LogCall");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
+ {
+ b.Property("IdxLogLic")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("Chiave")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CodApp")
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("CodInst")
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Descrizione")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IdxLic")
+ .HasColumnType("int");
+
+ b.Property("NumLicenze")
+ .HasColumnType("int");
+
+ b.Property("Scadenza")
+ .HasColumnType("datetime2");
+
+ b.Property("Tipo")
+ .HasColumnType("int");
+
+ b.HasKey("IdxLogLic");
+
+ b.HasIndex("CodApp");
+
+ b.HasIndex("CodInst");
+
+ b.HasIndex("IdxLic");
+
+ b.ToTable("LogLicenze");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.SubLicenzaModel", b =>
+ {
+ b.Property("IdxSubLic")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("Chiave")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CodImpiego")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("IdxLic")
+ .HasColumnType("int");
+
+ b.Property("Tipo")
+ .HasColumnType("int");
+
+ b.Property("VetoUnlock")
+ .HasColumnType("datetime2");
+
+ b.HasKey("IdxSubLic");
+
+ b.HasIndex("IdxLic");
+
+ b.ToTable("SubLicenze");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.TicketModel", b =>
+ {
+ b.Property("IdxTicket")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("CodImpiego")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ContactEmail")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ContactName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ContactPhone")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DtReq")
+ .HasColumnType("datetime2");
+
+ b.Property("IdxLic")
+ .HasColumnType("int");
+
+ b.Property("IdxSubLic")
+ .HasColumnType("int");
+
+ b.Property("ReqBody")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("SupplAnsw")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SupplEmail")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SupplUserCode")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Tipo")
+ .HasColumnType("int");
+
+ b.HasKey("IdxTicket");
+
+ b.HasIndex("IdxLic");
+
+ b.ToTable("TicketLog");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
+ {
+ b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
+ .WithMany()
+ .HasForeignKey("CodApp");
+
+ b.HasOne("LiMan.DB.DBModels.InstallazioneModel", "InstallazioneNav")
+ .WithMany()
+ .HasForeignKey("CodInst");
+
+ b.Navigation("ApplicativoNav");
+
+ b.Navigation("InstallazioneNav");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
+ {
+ b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
+ .WithMany()
+ .HasForeignKey("CodApp");
+
+ b.HasOne("LiMan.DB.DBModels.InstallazioneModel", "InstallazioneNav")
+ .WithMany()
+ .HasForeignKey("CodInst");
+
+ b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
+ .WithMany()
+ .HasForeignKey("IdxLic")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ApplicativoNav");
+
+ b.Navigation("InstallazioneNav");
+
+ b.Navigation("LicenzaNav");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.SubLicenzaModel", b =>
+ {
+ b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
+ .WithMany("Attivazioni")
+ .HasForeignKey("IdxLic")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("LicenzaNav");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.TicketModel", b =>
+ {
+ b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
+ .WithMany("Tickets")
+ .HasForeignKey("IdxLic")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("LicenzaNav");
+ });
+
+ modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
+ {
+ b.Navigation("Attivazioni");
+
+ b.Navigation("Tickets");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/LiMan.DB/Migrations/20211117101539_AddLogCalls.cs b/LiMan.DB/Migrations/20211117101539_AddLogCalls.cs
new file mode 100644
index 0000000..3bf3604
--- /dev/null
+++ b/LiMan.DB/Migrations/20211117101539_AddLogCalls.cs
@@ -0,0 +1,32 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace LiMan.DB.Migrations
+{
+ public partial class AddLogCalls : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "LogCall",
+ columns: table => new
+ {
+ DataRif = table.Column(type: "datetime2", nullable: false),
+ CodInst = table.Column(type: "nvarchar(450)", nullable: false),
+ CodApp = table.Column(type: "nvarchar(450)", nullable: false),
+ TargetUrl = table.Column(type: "nvarchar(450)", nullable: false),
+ NumCall = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LogCall", x => new { x.DataRif, x.CodInst, x.CodApp, x.TargetUrl });
+ });
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "LogCall");
+ }
+ }
+}
diff --git a/LiMan.DB/Migrations/LMDbContextModelSnapshot.cs b/LiMan.DB/Migrations/LMDbContextModelSnapshot.cs
index b342fbd..b52d5fc 100644
--- a/LiMan.DB/Migrations/LMDbContextModelSnapshot.cs
+++ b/LiMan.DB/Migrations/LMDbContextModelSnapshot.cs
@@ -111,6 +111,28 @@ namespace LiMan.DB.Migrations
b.ToTable("Licenze");
});
+ modelBuilder.Entity("LiMan.DB.DBModels.LogCallModel", b =>
+ {
+ b.Property("DataRif")
+ .HasColumnType("datetime2");
+
+ b.Property("CodInst")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("CodApp")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("TargetUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("NumCall")
+ .HasColumnType("int");
+
+ b.HasKey("DataRif", "CodInst", "CodApp", "TargetUrl");
+
+ b.ToTable("LogCall");
+ });
+
modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
{
b.Property("IdxLogLic")
diff --git a/LiMan.GLS/LiMan.GLS.csproj b/LiMan.GLS/LiMan.GLS.csproj
index 78f11cb..f77e57e 100644
--- a/LiMan.GLS/LiMan.GLS.csproj
+++ b/LiMan.GLS/LiMan.GLS.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net5.0
diff --git a/LiMan.UI/Data/LiManDataService.cs b/LiMan.UI/Data/LiManDataService.cs
index 457d60b..a4bd2c1 100644
--- a/LiMan.UI/Data/LiManDataService.cs
+++ b/LiMan.UI/Data/LiManDataService.cs
@@ -11,6 +11,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static LiMan.DB.Enum;
+using Microsoft.AspNetCore.Identity.UI.Services;
namespace LiMan.UI.Data
{
@@ -20,8 +21,8 @@ namespace LiMan.UI.Data
private static IConfiguration _configuration;
private static ILogger _logger;
-
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
+ private readonly IEmailSender _emailSender;
private readonly IDistributedCache distributedCache;
private readonly IMemoryCache memoryCache;
@@ -54,10 +55,11 @@ namespace LiMan.UI.Data
#region Public Constructors
- public LiManDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache)
+ public LiManDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache, IEmailSender emailSender)
{
_logger = logger;
_configuration = configuration;
+ _emailSender = emailSender;
// conf cache
this.memoryCache = memoryCache;
this.distributedCache = distributedCache;
@@ -547,6 +549,20 @@ namespace LiMan.UI.Data
dbControllerGLS.rollBackEntity(item);
}
+ public async Task SendEmail(string destEmail, string oggetto, string corpo)
+ {
+ bool answ = false;
+ try
+ {
+ await _emailSender.SendEmailAsync(destEmail, oggetto, corpo);
+ answ = true;
+ }
+ catch
+ { }
+
+ return answ;
+ }
+
///
/// Aggiornamentos tato ticket
///
diff --git a/LiMan.UI/LiMan.UI.csproj b/LiMan.UI/LiMan.UI.csproj
index 61fb80c..01a4c35 100644
--- a/LiMan.UI/LiMan.UI.csproj
+++ b/LiMan.UI/LiMan.UI.csproj
@@ -1,8 +1,8 @@
- net6.0
- 1.1.2111.1618
+ net5.0
+ 1.1.2111.1719
LiMan.UI
LiMan.UI
diff --git a/LiMan.UI/Properties/PublishProfiles/IIS01.pubxml b/LiMan.UI/Properties/PublishProfiles/IIS01.pubxml
index 81e712b..94ebf7d 100644
--- a/LiMan.UI/Properties/PublishProfiles/IIS01.pubxml
+++ b/LiMan.UI/Properties/PublishProfiles/IIS01.pubxml
@@ -22,7 +22,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
True
jenkins
<_SavePWD>True
- net6.0
+ net5.0
false
\ No newline at end of file
diff --git a/LiMan.UI/Properties/PublishProfiles/IIS02.pubxml b/LiMan.UI/Properties/PublishProfiles/IIS02.pubxml
index 1847a26..aaca518 100644
--- a/LiMan.UI/Properties/PublishProfiles/IIS02.pubxml
+++ b/LiMan.UI/Properties/PublishProfiles/IIS02.pubxml
@@ -22,7 +22,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
True
jenkins
<_SavePWD>True
- net6.0
+ net5.0
false
\ No newline at end of file
diff --git a/LiMan.UI/Properties/PublishProfiles/W2019-IIS-DEV.pubxml b/LiMan.UI/Properties/PublishProfiles/W2019-IIS-DEV.pubxml
index 3aaee28..c727b14 100644
--- a/LiMan.UI/Properties/PublishProfiles/W2019-IIS-DEV.pubxml
+++ b/LiMan.UI/Properties/PublishProfiles/W2019-IIS-DEV.pubxml
@@ -22,7 +22,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
True
jenkins
<_SavePWD>True
- net6.0
+ net5.0
false
\ No newline at end of file
diff --git a/LiMan.UI/Resources/ChangeLog.html b/LiMan.UI/Resources/ChangeLog.html
index 89f81a8..8d7b79a 100644
--- a/LiMan.UI/Resources/ChangeLog.html
+++ b/LiMan.UI/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
License Manager
- Versione: 1.1.2111.1618
+ Versione: 1.1.2111.1719
Note di rilascio:
diff --git a/LiMan.UI/Resources/VersNum.txt b/LiMan.UI/Resources/VersNum.txt
index 352ab4e..7232e07 100644
--- a/LiMan.UI/Resources/VersNum.txt
+++ b/LiMan.UI/Resources/VersNum.txt
@@ -1 +1 @@
-1.1.2111.1618
+1.1.2111.1719
diff --git a/LiMan.UI/Resources/manifest.xml b/LiMan.UI/Resources/manifest.xml
index 59648ab..9cfa5fd 100644
--- a/LiMan.UI/Resources/manifest.xml
+++ b/LiMan.UI/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 1.1.2111.1618
+ 1.1.2111.1719
https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.UI.zip
https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html
false
diff --git a/LiMan.UI/Startup.cs b/LiMan.UI/Startup.cs
index 2bae00f..57cfb22 100644
--- a/LiMan.UI/Startup.cs
+++ b/LiMan.UI/Startup.cs
@@ -1,3 +1,4 @@
+using LiMan.DB;
using LiMan.UI.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
@@ -13,6 +14,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity.UI.Services;
namespace LiMan.UI
{
@@ -97,6 +99,18 @@ namespace LiMan.UI
options.InstanceName = "LiMan";
});
+ // abilitazione x email management con MailKit
+ services.AddTransient();
+ services.Configure(options =>
+ {
+ options.Host_Address = Configuration["ExternalProviders:MailKit:SMTP:Address"];
+ options.Host_Port = Convert.ToInt32(Configuration["ExternalProviders:MailKit:SMTP:Port"]);
+ options.Host_Username = Configuration["ExternalProviders:MailKit:SMTP:Account"];
+ options.Host_Password = Configuration["ExternalProviders:MailKit:SMTP:Password"];
+ options.Sender_EMail = Configuration["ExternalProviders:MailKit:SMTP:SenderEmail"];
+ options.Sender_Name = Configuration["ExternalProviders:MailKit:SMTP:SenderName"];
+ });
+
services.AddLocalization();
services.AddRazorPages();
diff --git a/LiMan.UI/appsettings.json b/LiMan.UI/appsettings.json
index ad09909..4667c39 100644
--- a/LiMan.UI/appsettings.json
+++ b/LiMan.UI/appsettings.json
@@ -1,15 +1,31 @@
{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "AllowedHosts": "*",
- "ConnectionStrings": {
- "LiMan.GLS": "Server=SQLSTEAM;Database=SteamWare_Auth;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.UI;",
- "LiMan.DB": "Server=SQLSTEAM;Database=LiMan.DB;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.UI;",
- "Redis": "localhost:6379"
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
}
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "LiMan.GLS": "Server=SQLSTEAM;Database=SteamWare_Auth;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.UI;",
+ "LiMan.DB": "Server=SQLSTEAM;Database=LiMan.DB;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.UI;",
+ "Redis": "localhost:6379"
+ },
+ "ExternalProviders": {
+ "MailKit": {
+ "SMTP": {
+ "Address": "smtp.gmail.com",
+ "Port": "465",
+ "Account": "steamwarebot@gmail.com",
+ "Password": "drmfsls16",
+ "SenderEmail": "steamwarebot@gmail.com",
+ "SenderName": "Steamware Email BOT"
+ }
+ }
+ },
+ "MailDest": {
+ "Admin": "samuele@steamware.net",
+ "ProcOp": "ceo@steamware.net"
+ }
}
\ No newline at end of file