public static TokenSet ToTokenSet(this ActionstepCredential actionstepCredential) { if (actionstepCredential is null) { throw new ArgumentNullException(nameof(actionstepCredential)); } if (actionstepCredential.Owner is null) { throw new ArgumentException( $"The property '{nameof(ActionstepCredential.Owner)}' must be set to create a valid '{nameof(TokenSet)}'."); } if (actionstepCredential.ActionstepOrg is null) { throw new ArgumentException( $"The property '{nameof(ActionstepCredential.ActionstepOrg)}' must be set to create a valid '{nameof(TokenSet)}'."); } var tokenSet = new TokenSet( actionstepCredential.AccessToken, actionstepCredential.TokenType, actionstepCredential.ExpiresIn, actionstepCredential.ApiEndpoint, actionstepCredential.ActionstepOrg.Key, actionstepCredential.RefreshToken, Instant.FromDateTimeUtc(actionstepCredential.ReceivedAtUtc), actionstepCredential.Owner.Id.ToString(CultureInfo.InvariantCulture), actionstepCredential.Id.ToString(CultureInfo.InvariantCulture), actionstepCredential.IdToken, actionstepCredential.RevokedAtUtc.HasValue ? Instant.FromDateTimeUtc(actionstepCredential.RevokedAtUtc.Value) : (Instant?)null); if (actionstepCredential.LockId != Guid.Empty) { tokenSet.RefreshLockInfo = new TokenSetRefreshLockInfo( Instant.FromDateTimeUtc(actionstepCredential.LockExpiresAtUtc), actionstepCredential.LockId); } return(tokenSet); }
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(); }
public static void UpdateFromTokenSet(this ActionstepCredential actionstepCredential, TokenSet tokenSet) { if (actionstepCredential is null) { throw new ArgumentNullException(nameof(actionstepCredential)); } if (tokenSet is null) { throw new ArgumentNullException(nameof(tokenSet)); } if (!string.IsNullOrEmpty(tokenSet.Id)) { if (tokenSet.Id != actionstepCredential.Id.ToString(CultureInfo.InvariantCulture)) { throw new TokenSetIdDoesntMatchActionstepCredentialIdException(actionstepCredential.Id, tokenSet.Id); } } if (tokenSet.OrgKey != actionstepCredential.ActionstepOrg?.Key) { throw new TokenSetOrgDoesntMatchActionstepCredentialOrgException(actionstepCredential.ActionstepOrg?.Key, tokenSet.OrgKey, tokenSet.Id); } if (!string.IsNullOrEmpty(tokenSet.UserId)) { if (tokenSet.UserId != actionstepCredential.Owner?.Id) { throw new TokenSetUserDoesntMatchActionstepCredentialUserException(actionstepCredential.Owner?.Id, tokenSet.UserId, tokenSet.Id); } } actionstepCredential.AccessToken = tokenSet.AccessToken; actionstepCredential.AccessTokenExpiryUtc = tokenSet.AccessTokenExpiresAt.ToDateTimeUtc(); actionstepCredential.TokenType = tokenSet.TokenType; actionstepCredential.ExpiresIn = tokenSet.ExpiresIn; actionstepCredential.ApiEndpoint = tokenSet.ApiEndpoint; actionstepCredential.RefreshToken = tokenSet.RefreshToken; actionstepCredential.RefreshTokenExpiryUtc = tokenSet.RefreshTokenExpiresAt.ToDateTimeUtc(); actionstepCredential.ReceivedAtUtc = tokenSet.ReceivedAt.ToDateTimeUtc(); actionstepCredential.IdToken = tokenSet.IdToken; if (tokenSet.RevokedAt.HasValue) { actionstepCredential.RevokedAtUtc = tokenSet.RevokedAt.Value.ToDateTimeUtc(); } else { actionstepCredential.RevokedAtUtc = null; } if (tokenSet.RefreshLockInfo is null) { actionstepCredential.LockExpiresAtUtc = DateTime.MinValue; actionstepCredential.LockId = Guid.Empty; } else { actionstepCredential.LockExpiresAtUtc = tokenSet.RefreshLockInfo.LockExpiresAt.ToDateTimeUtc(); actionstepCredential.LockId = tokenSet.RefreshLockInfo.LockId; } }
/// <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()); }