private void PrepareTestData(IServiceProvider serviceProvider) { var dbContext = serviceProvider.GetService <WCADbContext>(); var testUser = dbContext.GetTestUser(); var actionstepOrg = new ActionstepOrg { Key = "testOrg", Title = "testOrg", CreatedBy = testUser, DateCreatedUtc = DateTime.UtcNow }; dbContext.ActionstepOrgs.Add(actionstepOrg); dbContext.SaveChanges(); var startTime = DateTime.UtcNow; var actionstepCredential = new ActionstepCredential { AccessToken = "testToken", AccessTokenExpiryUtc = startTime.AddMinutes(20), ActionstepOrg = actionstepOrg, ApiEndpoint = new Uri("http://test-endpoint/api"), CreatedBy = testUser, DateCreatedUtc = startTime, ExpiresIn = 60 * 20, ReceivedAtUtc = startTime, Owner = testUser, RefreshToken = "testRefreshToken", RefreshTokenExpiryUtc = startTime.AddDays(20), TokenType = "bearer" }; dbContext.ActionstepCredentials.Add(actionstepCredential); dbContext.SaveChanges(); }
/// <summary> /// /// </summary> /// <param name="tokenSet"></param> /// <returns></returns> /// <exception cref="KeyNotFoundException">Thrown if a tokenSet could not be found with the specified ID.</exception> public async Task <TokenSet> AddOrUpdateTokenSet(TokenSet tokenSet) { // Use a separate scope for each method call to prevent DBContext caching using var scope = _serviceScopeFactory.CreateScope(); using var dbContext = scope.ServiceProvider.GetService <WCADbContext>(); if (tokenSet is null) { throw new ArgumentNullException(nameof(tokenSet)); } _telemetry.TrackEvent(nameof(AddOrUpdateTokenSet), new Dictionary <string, string>() { { "TokenSetId", tokenSet.Id }, { "RefreshLockInfo ExpiresAt", tokenSet.RefreshLockInfo?.LockExpiresAt.ToString() }, { "RefreshLockInfo LockId", tokenSet.RefreshLockInfo?.LockId.ToString() }, }); ActionstepCredential actionstepCredential = null; var tokenSetUser = await dbContext.Users.FindAsync(tokenSet.UserId); if (tokenSetUser is null) { throw new UserNotFoundException("Couldn't find user attempting to add or update TokenSet.", tokenSet.UserId); } if (!string.IsNullOrEmpty(tokenSet.Id)) { var tokenSetId = int.Parse(tokenSet.Id, CultureInfo.InvariantCulture); actionstepCredential = await dbContext.ActionstepCredentials .Include(c => c.Owner) .Include(c => c.ActionstepOrg) .SingleOrDefaultAsync(c => c.Id == tokenSetId); } // If not found by id, attempt to find by user and org if (actionstepCredential is null) { actionstepCredential = await dbContext.ActionstepCredentials .Include(c => c.Owner) .Include(c => c.ActionstepOrg) .ForOwnerAndOrg(tokenSetUser, tokenSet.OrgKey) .SingleOrDefaultAsync(); } var now = _clock.GetCurrentInstant().ToDateTimeUtc(); // If still null, then we need to create it if (actionstepCredential is null) { actionstepCredential = new ActionstepCredential(); actionstepCredential.Owner = tokenSetUser; actionstepCredential.CreatedBy = tokenSetUser; actionstepCredential.DateCreatedUtc = now; dbContext.ActionstepCredentials.Add(actionstepCredential); } if (actionstepCredential.ActionstepOrg == null || actionstepCredential.ActionstepOrg.Key == null) { var orgToAssociate = dbContext.ActionstepOrgs.Where(o => o.Key == tokenSet.OrgKey).SingleOrDefault(); if (orgToAssociate == null) { var newOrg = new ActionstepOrg() { Key = tokenSet.OrgKey, Title = tokenSet.OrgKey, CreatedBy = actionstepCredential.Owner, DateCreatedUtc = now, UpdatedBy = actionstepCredential.Owner, LastUpdatedUtc = now, }; EntityEntry <ActionstepOrg> addedOrgEntity = dbContext.ActionstepOrgs.Add(newOrg); orgToAssociate = addedOrgEntity.Entity; } actionstepCredential.ActionstepOrg = orgToAssociate; } else { if (!actionstepCredential.ActionstepOrg.Key.Equals(tokenSet.OrgKey, StringComparison.InvariantCulture)) { throw new TokenSetOrgKeyMismatchException( "An attempt was made to update a TokenSet, however the Actionstep org key supplied in the TokenSet doesn't match the saved org key stored.", actionstepCredential.ActionstepOrg.Key, tokenSet); } } /// Copies simple field mappings, except things like org because it's a complex relationship in <see cref="ActionstepCredential"/>. actionstepCredential.UpdateFromTokenSet(tokenSet); actionstepCredential.UpdatedBy = tokenSetUser; actionstepCredential.LastUpdatedUtc = now; actionstepCredential.ConcurrencyStamp = Guid.NewGuid(); try { await dbContext.SaveChangesAsync(); } catch (DbUpdateConcurrencyException dbConcurrencyException) { throw new TokenSetConcurrencyException(tokenSet, dbConcurrencyException); } return(actionstepCredential.ToTokenSet()); }