using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Moq; using Strata.ContinuousImprovement.Biz.DbContexts; using Strata.ContinuousImprovement.Biz.OpportunityTypeWorkbooks; using Strata.ContinuousImprovement.Biz.OpportunityWorkbooks; using Strata.ContinuousImprovement.Client.Test.Integration.Models; using Strata.ContinuousImprovement.Client.Test.Integration.Setup; using Strata.CoreLib.Claims; using Strata.CoreLib.Claims.Extensions; using System.IdentityModel.Tokens.Jwt; using System.Net.Http.Headers; using System.Security.Claims; using System.Text.Json; namespace Strata.ContinuousImprovement.Client.Test.Integration.Tests { public class ClientServiceBase { protected StrataTokenInfo StrataTokenInfo { get; set; } protected string AccessToken { get; set; } protected IEnumerable Claims { get; set; } protected long ExpiresIn { get; set; } protected ClaimsIdentity ClaimsIdentity { get; set; } protected ClaimsPrincipal ClaimsPrincipal { get; set; } internal IClaimsPrincipalAccessor ClaimsPrincipalAccessor { get; set; } internal int StrataId { get; set; } internal Guid DatabaseGuid { get; set; } protected readonly string BaseAddress = "https://continuousimprovement-api.dev.stratanetwork.net/"; public IContinuousImprovementService ContinuousImprovementService { get; set; } public JazzDbContext JazzDbContext { get; set; } public CentralDbContext CentralDbContext { get; set; } public IOpportunityWorkbookService OpportunityWorkbookService { get; set; } #pragma warning disable NUnit1032 // An IDisposable field/property should be Disposed in a TearDown method public IServiceProvider ServiceProvider { get; set; } #pragma warning restore NUnit1032 // An IDisposable field/property should be Disposed in a TearDown method public OpportunityWorkbook OpportunityWorkbook { get; set; } public OpportunityTypeWorkbook OpportunityTypeWorkbook { get; set; } [OneTimeSetUp] public async Task TestSetup() { ServiceProvider = ServiceProperties.ServiceProvider; await ClientValidation(); var httpClient = new HttpClient { BaseAddress = new Uri(BaseAddress) }; httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); ContinuousImprovementService = new ContinuousImprovementService(httpClient); ServiceProperties.ContinuousImprovementService = ContinuousImprovementService; CentralDbContext = (CentralDbContext)ServiceProperties.CentralDbContext; JazzDbContext = (JazzDbContext)ServiceProperties.JazzDbContext; await ReplaceOpportunitWorkbookService(); } [OneTimeTearDown] public async Task TestTearDown() { ((ServiceProvider)ServiceProvider).Dispose(); } private async Task ReplaceOpportunitWorkbookService() { var claimsAccessor = Mock.Of(); Mock.Get(claimsAccessor) .Setup(s => s.GetCurrentClaimsPrincipal()) .Returns(ClaimsPrincipal); var analyticsService = ServiceProperties.AnalyticsService; OpportunityWorkbookService = new OpportunityWorkbookService(CentralDbContext, analyticsService, claimsAccessor, Mock.Of>()); var services = ServiceProperties.Services; var descriptor = services.FirstOrDefault(d => d.ServiceType == typeof(IOpportunityWorkbookService)); if (descriptor != null) { services.Remove(descriptor); services.AddScoped(); ServiceProvider = services.BuildServiceProvider(); } OpportunityWorkbook = await CentralDbContext.OpportunityWorkbooks.FirstOrDefaultAsync(CancellationToken.None); OpportunityTypeWorkbook = await CentralDbContext.OpportunityTypeWorkbooks.FirstOrDefaultAsync(CancellationToken.None); } #region Client Claims Validation public async Task ClientValidation() { var UserInfo = new { vaultUserName = "ccicostleader", // vault ccicostleader is same as jazz ccicostleader userName = "ccicostleader", fullName = "Administrator, CCI" }; var vaultPassword = await GetUserPassword(UserInfo.vaultUserName); var bearerToken = await GetBearerToken(UserInfo.userName, vaultPassword); ClaimsIdentity = new ClaimsIdentity(Claims); ClaimsPrincipal = new ClaimsPrincipal(ClaimsIdentity); StrataId = ClaimsPrincipal.GetStrataId(); DatabaseGuid = ClaimsPrincipal.GetDatabaseGuid(); BuildClaimsPrincipalAccessor(); return bearerToken; } internal async Task GetUserPassword(string vaultUserName) { var client = new HttpClient { BaseAddress = new Uri("https://vault.sdt.local/") }; client.DefaultRequestHeaders.Add("apiKey", "a69d2e478c3f5b395b687ecdf34a3239"); client.DefaultRequestHeaders.Add("ignoreHTTPSErrors", "true"); var vaultResponse = await client.GetAsync($"api/searchpasswords/122?title={vaultUserName}"); vaultResponse.EnsureSuccessStatusCode(); string responseString = await vaultResponse.Content.ReadAsStringAsync(); if (string.IsNullOrEmpty(responseString)) { return string.Empty; } var jsonResponse = JsonSerializer.Deserialize>(responseString); if (jsonResponse == null) { return string.Empty; } var vaultUserInfo = jsonResponse.First(); client.Dispose(); return vaultUserInfo.Password; } internal async Task GetBearerToken(string userName, string password) { var form = BuildTokenRequest(userName, password); var client = new HttpClient(); var response = await client.PostAsync("https://identity.dev.stratanetwork.net/connect/token", form); response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); if (string.IsNullOrEmpty(responseString)) { return string.Empty; } var strataTokenInfo = JsonSerializer.Deserialize(responseString); if (strataTokenInfo == null) { return string.Empty; } StrataTokenInfo = strataTokenInfo; AccessToken = strataTokenInfo.AccessToken; ExpiresIn = strataTokenInfo.ExpiresIn; var handler = new JwtSecurityTokenHandler(); var jwtToken = handler.ReadJwtToken(AccessToken); Claims = jwtToken.Claims; client.Dispose(); return AccessToken; } internal FormUrlEncodedContent BuildTokenRequest(string userName, string password) { var form = new FormUrlEncodedContent( [ new KeyValuePair("database_guid", ServiceProperties.DatabaseGuid.ToString()), new KeyValuePair("grant_type", "password"), new KeyValuePair("username", userName), new KeyValuePair("password", password), new KeyValuePair("scope", "strata.api.external offline_access"), new KeyValuePair("client_id", "IntegrationTest"), new KeyValuePair("client_secret", "UhAEQsGByTCrwPdHPLmaet_DmLEfcJVbZqGBxArdeRup_TPLrYKNpUNRHejjdnhd") ]); return form; } internal void BuildClaimsPrincipalAccessor() { var claimsAccessor = Mock.Of(); Mock.Get(claimsAccessor) .Setup(s => s.GetCurrentClaimsPrincipal()) .Returns(ClaimsPrincipal); ClaimsPrincipalAccessor = claimsAccessor; } #endregion #region Helper Methods protected async Task> GetConfigurationsAsync(CancellationToken cancellationToken) { var configurations = await JazzDbContext.Configurations.ToListAsync(cancellationToken); return configurations.Select(c => c.Mapped()); } #endregion } }