using System; using System.Linq; using System.Text; using System.Text.Json; using Iit.OAPI.Tools.Monitor.Common; using Iit.OAPI.Tools.Monitor.Common.Configuration; using Iit.OAPI.Tools.Monitor.Common.Enums; using Iit.OAPI.Tools.Monitor.Common.Models.Correlation; using Iit.OAPI.Tools.Monitor.Common.Security; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Options; using System.Collections.Generic; namespace Iit.OAPI.Tools.Monitor.UI.Pages.OpenApi { public class KeysModel : PageModel { private readonly OpenApiTokenConfiguration _openApiTokenConfiguration; private readonly IUIHelper _uiHelper; public KeysModel(IOptions<OpenApiTokenConfiguration> openApiTokenConfiguration, IUIHelper uiHelper) { _openApiTokenConfiguration = openApiTokenConfiguration.Value; _uiHelper = uiHelper; } public string KeyIn { get; private set; } = string.Empty; public string Result { get; private set; } = string.Empty; public List<string> ResultList { get; private set; } = new(); [BindProperty(SupportsGet = true)] public string Environment { get; set; } = "Live"; public HostingTypes Hosting { get; set; } = HostingTypes.OnPrem | HostingTypes.AKS; public int ApplicationId { get; set; } = 0; public List<string> Environments { get; private set; } = new(); public ElasticCluster? ClusterForAks { get; private set; } public ElasticCluster? ClusterForOnPrem { get; private set; } public long TotalHits { get; private set; } public long TotalBytesSent { get; private set; } public long CompareTo { get; private set; } public async void OnGet([FromQuery(Name = "keyin")] string keyIn) { Environments = await _uiHelper.TopologyEnvironmentNamesAsync().ConfigureAwait(false); var url = Environment; StringBuilder sb = new(); if (!string.IsNullOrEmpty(keyIn)) { KeyIn = keyIn; try { // correlation key? var parts = keyIn.Split('#', StringSplitOptions.RemoveEmptyEntries); if (parts.Length > 2) { // {sessionId}#{AppId}#{requestId}#{serverDigits} sb.Append("Looks like a correlation key with the following elements:<ul>"); sb.Append($"<li>SessionId: {parts[0]}</li>"); sb.Append($"<li> AppId: {parts[1]}</li>"); sb.Append($"<li> RequestId: {parts[2]}</li>"); if (parts.Length > 3) { sb.Append($"<li>Response came from server with digits: {parts[3]}</li>"); } sb.Append("</ul>"); } //foreach (var str in parts){ // StringBuilder strb = new(); // strb.Append("https://"); // strb.Append($"elastic.mid.dom:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(columns:!(),filters:!(('$state':(store:appState)," + // $"meta:(alias:!n,disabled:!f,index:'openapi-iis-live-*',key:correlation.sessionid,negate:!f,params:(query:'{str}'),"); // strb.Append($"type:phrase),query:(match_phrase:(correlation.sessionid:'{str}')))),"); // strb.Append("index:'openapi-iis-live-*',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"); // ResultList.Add(strb.ToString()); //} var firstPart = sb.ToString(); ResultList.Add(firstPart); StringBuilder sb2 = new(); var sessionId = parts[0]; var applicationId = parts[1]; var requestId = parts[2]; var integer = parts[3]; sb2.Append("https://"); sb2.Append($"elastic.mid.dom:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-24h%2Fh,to:now))&_a=(columns:!(),filters:!(('$state':(store:appState)," + $"meta:(alias:!n,disabled:!f,index:'openapi-iis-live-*',key:correlation.sessionid,negate:!f,params:(query:'{sessionId}'),"); sb2.Append($"type:phrase),query:(match_phrase:(correlation.sessionid:'{sessionId}')))),"); sb2.Append("index:'openapi-iis-live-*',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"); var secondString = sb2.ToString(); ResultList.Add(secondString); StringBuilder sb3 = new(); sb3.Append("https://"); sb3.Append($"elastic.mid.dom:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-24h%2Fh,to:now))&_a=(columns:!(),filters:!(('$state':(store:appState)," + $"meta:(alias:!n,disabled:!f,index:'openapi-iis-live-*',key:correlation.appid,negate:!f,params:(query:'{applicationId}'),"); sb3.Append($"type:phrase),query:(match_phrase:(correlation.appid:'{applicationId}')))),"); sb3.Append("index:'openapi-iis-live-*',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"); var thirdString = sb3.ToString(); ResultList.Add(thirdString); StringBuilder sb4 = new(); sb4.Append("https://"); sb4.Append($"elastic.mid.dom:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-24h%2Fh,to:now))&_a=(columns:!(),filters:!(('$state':(store:appState)," + $"meta:(alias:!n,disabled:!f,index:'openapi-iis-live-*',key:correlation.requestid,negate:!f,params:(query:'{requestId}'),"); sb4.Append($"type:phrase),query:(match_phrase:(correlation.requestid:'{requestId}')))),"); sb4.Append("index:'openapi-iis-live-*',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"); var forthString = sb4.ToString(); ResultList.Add(forthString); } catch { } try { // token payload? if (sb.Length == 0) { string payload = Utilities.Base64DecodeUrlSafe(keyIn); if (!string.IsNullOrEmpty(payload) && (_openApiTokenConfiguration.Environments != null)) { sb.Append($"Token payload: {payload}"); // try to decrypt (all four environments) CorrelationData corData = new(); foreach (var type in Enum.GetValues(typeof(EnvironmentType)).Cast<EnvironmentType>()) { var token = _openApiTokenConfiguration.Environments.FirstOrDefault(w => w.EnvironmentType == type); if ((token != null) && !string.IsNullOrEmpty(token.EncryptionKey) && !string.IsNullOrEmpty(token.Vector)) { corData = Utilities.CorrelationObjectFromTokenPayload(null, corData, payload, token.EncryptionKey, token.Vector); } } JsonSerializerOptions options = new() { IgnoreNullValues = true, WriteIndented = true }; sb.Append($"<br/><br/>Decrypted correlation data: {JsonSerializer.Serialize(corData, options)}"); } } } catch { } try { // encrypted key? if ((sb.Length == 0) && (_openApiTokenConfiguration.Environments != null)) { // try to decrypt (all four environments) foreach (var type in Enum.GetValues(typeof(EnvironmentType)).Cast<EnvironmentType>()) { var token = _openApiTokenConfiguration.Environments.FirstOrDefault(w => w.EnvironmentType == type); if ((token != null) && !string.IsNullOrEmpty(token.EncryptionKey) && !string.IsNullOrEmpty(token.Vector)) { var decryptedKey = IdentityEncrypter.Decrypt(keyIn, token.EncryptionKey, token.Vector); if (!string.IsNullOrEmpty(decryptedKey)) { sb.Append($"This is a key from a '{type}' environment, "); sb.Append($"with the value '{decryptedKey}'."); break; } } } } } catch { } // not able to find out what it is if (sb.Length == 0) { sb.Append("No idea what that is."); } } Result = sb.ToString(); } public void ResultCorelationId([FromQuery(Name = "sessionkey")] string keyIn) { StringBuilder sb = new(); if (!string.IsNullOrEmpty(keyIn)) { KeyIn = keyIn; try { // correlation key var parts = keyIn.Split('#', StringSplitOptions.RemoveEmptyEntries); var sessionId = parts[0]; var applicationId = parts[1]; var requestId = parts[2]; var integer = parts[3]; sb.Append("https://"); sb.Append($"elastic.mid.dom:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(columns:!(),filters:!(('$state':(store:appState)," + $"meta:(alias:!n,disabled:!f,index:'openapi-iis-live-*',key:correlation.sessionid,negate:!f,params:(query:'{sessionId}'),"); sb.Append($"type:phrase),query:(match_phrase:(correlation.sessionid:'{sessionId}')))),"); sb.Append("index:'openapi-iis-live-*',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"); } catch { } // not able to find out what it is if (sb.Length == 0) { sb.Append("No idea what that is."); } } } } }