private void CreateEntity(Entity crmEntity, DataImportResult result = null) { _logger.LogVerbose($"Creating {crmEntity.LogicalName} entity with Id: '{crmEntity.Id}'"); try { _crmService.Create(crmEntity.ToEntity <Entity>()); if (result != null) { result.RecordsCreated++; } } catch (FaultException <OrganizationServiceFault> fex) { switch ((uint)fex.Detail.ErrorCode) { //Continue if key is duplicate //TODO: Behavior should be configurable case (uint)0x80040237: _logger.LogWarning($"Could not create {crmEntity.LogicalName} entity. Record with id: '{crmEntity.Id}' already exists."); if (result != null) { result.RecordsSkipped++; } break; default: throw; } } }
private void DeleteEntity(Entity crmEntity, DataImportResult result = null) { _logger.LogVerbose($"Deleting {crmEntity.LogicalName} entity with Id: '{crmEntity.Id}'"); try { _crmService.Delete(crmEntity.LogicalName, crmEntity.Id); if (result != null) { result.RecordsDeleted++; } } catch (FaultException <OrganizationServiceFault> fex) { switch ((uint)fex.Detail.ErrorCode) { //Continue if object does not exist //TODO: Behavior should be configurable case (uint)0x80040217: _logger.LogWarning($"Could not delete {crmEntity.LogicalName} entity with Id: '{crmEntity.Id}'. Object does not exist."); if (result != null) { result.RecordsSkipped++; } break; default: throw; } } }
private void UpdateEntity(JsonEntity crmEntity, Entity delta, DataImportResult result = null) { _logger.LogVerbose($"Updating {delta.LogicalName} entity with Id: '{delta.Id}'"); Entity fieldsToUpdate = null; switch (crmEntity.UpdateHint) { //Update all the fields regardless of whether or not they have changed case JsonEntity.UpdateHintEnum.AllFields: fieldsToUpdate = crmEntity.ToEntity <Entity>(); break; //If there is a change update all fields; otherwise update none case JsonEntity.UpdateHintEnum.AllOrNothing: fieldsToUpdate = delta.Attributes.Count == 0 ? delta : crmEntity.ToEntity <Entity>(); break; //Only update fields that have changed case JsonEntity.UpdateHintEnum.ChangedFields: fieldsToUpdate = delta; break; } try { if (fieldsToUpdate.Attributes.Count > 0) { _crmService.Update(fieldsToUpdate); if (result != null) { result.RecordsUpdated++; } } else { result.RecordsSkipped++; _logger.LogVerbose($"{fieldsToUpdate.LogicalName} entity with Id: '{fieldsToUpdate.Id} not updated'. No Attribute changes."); } } catch (FaultException <OrganizationServiceFault> fex) { switch ((uint)fex.Detail.ErrorCode) { //Continue if object does not exist //TODO: Behavior should be configurable case (uint)0x80040217: _logger.LogWarning($"Could not update {fieldsToUpdate.LogicalName} entity with Id: '{fieldsToUpdate.Id}'. Object does not exist."); if (result != null) { result.RecordsSkipped++; } break; default: throw; } } }
/// <summary> /// Cycle through all entities in the JSON file and perform specified operation /// </summary> /// <param name="crmData"></param> private DataImportResult ProcessDataFile(JObject crmData) { DataImportResult importResult = new DataImportResult(); //Retrieve all entities IList <JToken> entities = crmData.SelectToken("entities").ToList(); foreach (var jsonEntity in entities) { //Process the entities sequencially var crmEntity = jsonEntity.ToObject <JsonEntity>(_jsonSerializer); //Will look at using bulk updates in future switch (crmEntity.Operation) { case JsonEntity.OperationEnum.Delete: DeleteEntity(crmEntity); break; case JsonEntity.OperationEnum.Upsert: { //If the record exists update, otherwise create var existingEntity = RetrieveEntity(crmEntity); if (existingEntity != null) { //only update if fields have changed var delta = existingEntity.Delta(crmEntity); UpdateEntity(crmEntity, delta, importResult); } else { CreateEntity(crmEntity, importResult); } } break; case JsonEntity.OperationEnum.Create: CreateEntity(crmEntity, importResult); break; case JsonEntity.OperationEnum.Update: { //Calculate the Update Delta var existingEntity = RetrieveEntity(crmEntity); var delta = existingEntity.Delta(crmEntity); UpdateEntity(crmEntity, delta, importResult); break; } } } return(importResult); }
protected internal virtual async Task ImportAsyncScenarioTest(Context context, string fileName, ImportOptions importOptions, int expectedNumberOfErrors = 0, int expectedSavedChanges = 0, int expectedUsersAfterImport = 0) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (fileName == null) { throw new ArgumentNullException(nameof(fileName)); } if (importOptions == null) { throw new ArgumentNullException(nameof(importOptions)); } var serviceProvider = context.ServiceProvider; using (var serviceScope = serviceProvider.CreateScope()) { var identityContext = serviceScope.ServiceProvider.GetRequiredService <IdentityContext>(); var identityImporter = await this.CreateIdentityImporterAsync(serviceScope.ServiceProvider); var result = new DataImportResult(); await identityImporter.ImportAsync(await this.CreateConfigurationAsync(fileName, context.FileProvider), importOptions, result); if (!result.Errors.Any() && !importOptions.VerifyOnly) { result.SavedChanges = await identityContext.SaveChangesAsync(); } Assert.AreEqual(expectedNumberOfErrors, result.Errors.Count); Assert.AreEqual(expectedSavedChanges, result.SavedChanges); } using (var serviceScope = serviceProvider.CreateScope()) { var databaseContext = serviceScope.ServiceProvider.GetRequiredService <IdentityContext>(); Assert.IsFalse(await databaseContext.RoleClaims.AnyAsync()); Assert.IsFalse(await databaseContext.Roles.AnyAsync()); Assert.IsFalse(await databaseContext.UserClaims.AnyAsync()); Assert.IsFalse(await databaseContext.UserLogins.AnyAsync()); Assert.IsFalse(await databaseContext.UserRoles.AnyAsync()); Assert.IsFalse(await databaseContext.UserTokens.AnyAsync()); Assert.AreEqual(expectedUsersAfterImport, await databaseContext.Users.CountAsync()); } }
public async Task FilterOutInvalidModelsAsync_ShouldFilterOutEmptyIdentifiers() { var clients = new List <Client> { new Client { ClientId = string.Empty } }; var partialImporter = await this.CreatePartialImporterAsync(); var result = new DataImportResult(); await partialImporter.FilterOutInvalidModelsAsync(clients, result); Assert.IsFalse(clients.Any()); Assert.AreEqual(1, result.Errors.Count); Assert.AreEqual("Client.ClientId \"\" can not be empty.", result.Errors.First()); }
public async Task FilterOutDuplicateModelsAsync_ShouldFilterOutDuplicateIdentifiers() { const string clientId = "client"; var partialImporter = await this.CreatePartialImporterAsync(); var clients = new List <Client> { new Client { ClientId = clientId }, new Client { ClientId = clientId } }; var result = new DataImportResult(); await partialImporter.FilterOutDuplicateModelsAsync(clients, result); Assert.IsFalse(clients.Any()); Assert.AreEqual(1, result.Errors.Count); Assert.AreEqual($"Client.ClientId {clientId.ToStringRepresentation()} has 1 duplicate.", result.Errors.First()); clients = new List <Client> { new Client { ClientId = clientId }, new Client { ClientId = clientId }, new Client { ClientId = clientId } }; result = new DataImportResult(); await partialImporter.FilterOutDuplicateModelsAsync(clients, result); Assert.IsFalse(clients.Any()); Assert.AreEqual(1, result.Errors.Count); Assert.AreEqual($"Client.ClientId {clientId.ToStringRepresentation()} has 2 duplicates.", result.Errors.First()); }
protected internal virtual async Task ImportAsyncScenarioTest(Context context, string fileName, ImportOptions importOptions, int expectedNumberOfErrors = 0, int expectedRelyingPartiesAfterImport = 0, int expectedSavedChanges = 0) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (fileName == null) { throw new ArgumentNullException(nameof(fileName)); } if (importOptions == null) { throw new ArgumentNullException(nameof(importOptions)); } using (var serviceScope = context.ServiceProvider.CreateScope()) { var wsFederationConfigurationDatabaseContext = serviceScope.ServiceProvider.GetRequiredService <IWsFederationConfigurationDbContext>(); var wsFederationConfigurationImporter = await this.CreateWsFederationConfigurationImporterAsync(serviceScope.ServiceProvider); var result = new DataImportResult(); await wsFederationConfigurationImporter.ImportAsync(await this.CreateConfigurationAsync(fileName, context.FileProvider), importOptions, result); if (!result.Errors.Any() && !importOptions.VerifyOnly) { result.SavedChanges = await wsFederationConfigurationDatabaseContext.SaveChangesAsync(); } Assert.AreEqual(expectedNumberOfErrors, result.Errors.Count); Assert.AreEqual(expectedSavedChanges, result.SavedChanges); } using (var serviceScope = context.ServiceProvider.CreateScope()) { var wsFederationConfigurationDatabaseContext = serviceScope.ServiceProvider.GetRequiredService <IWsFederationConfigurationDbContext>(); Assert.AreEqual(expectedRelyingPartiesAfterImport, await wsFederationConfigurationDatabaseContext.RelyingParties.CountAsync()); } }
protected internal virtual async Task ImportAsyncChangesTest(DatabaseProvider databaseProvider) { using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationPluginBuilder = context.ServiceProvider.GetRequiredService <IWsFederationPluginBuilder>(); wsFederationPluginBuilder.Use(context.ApplicationBuilder); } using (var context = await this.CreateContextAsync(databaseProvider)) { Assert.IsFalse(await context.ServiceProvider.GetRequiredService <IWsFederationConfigurationDbContext>().RelyingParties.AnyAsync()); } var importOptions = new ImportOptions(); var relyingParties = new List <RelyingPartyModel> { new RelyingPartyModel { ClaimMapping = new Dictionary <string, string> { { "Key-1", "Value-1" }, { "Key-2", "Value-2" }, { "Key-3", "Value-3" } }, Realm = "Relying-party-1", TokenType = "Token-type" }, new RelyingPartyModel { ClaimMapping = new Dictionary <string, string> { { "Key-1", "Value-1" }, { "Key-2", "Value-2" } }, Realm = "Relying-party-2" }, new RelyingPartyModel { Realm = "Relying-party-3" } }; // Save relying-parties. using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationConfigurationImporter = await this.CreateWsFederationConfigurationImporterAsync(context.ServiceProvider); var relyingPartyImporter = wsFederationConfigurationImporter.Importers.OfType <RelyingPartyImporter>().First(); var result = new DataImportResult(); await relyingPartyImporter.ImportAsync(relyingParties, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(8, await wsFederationConfigurationImporter.CommitAsync()); } // Test relying-party properties. using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationConfigurationDatabaseContext = context.ServiceProvider.GetRequiredService <IWsFederationConfigurationDbContext>(); var relyingPartyStore = context.ServiceProvider.GetRequiredService <IRelyingPartyStore>(); var relyingPartyEntities = wsFederationConfigurationDatabaseContext.RelyingParties.ToArray(); Assert.AreEqual(3, relyingPartyEntities.Length); foreach (var relyingPartyEntity in relyingPartyEntities) { var relyingParty = await relyingPartyStore.FindRelyingPartyByRealm(relyingPartyEntity.Realm); Assert.AreEqual(relyingParty.ClaimMapping.Count, relyingPartyEntity.ClaimMapping.Count); Assert.AreEqual(relyingParty.DigestAlgorithm, relyingPartyEntity.DigestAlgorithm); Assert.AreEqual(relyingParty.Realm, relyingPartyEntity.Realm); Assert.AreEqual(relyingParty.SamlNameIdentifierFormat, relyingPartyEntity.SamlNameIdentifierFormat); Assert.AreEqual(relyingParty.SignatureAlgorithm, relyingPartyEntity.SignatureAlgorithm); Assert.AreEqual(relyingParty.TokenType, relyingPartyEntity.TokenType); } } // Save the same unchanged relying-parties again. using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationConfigurationImporter = await this.CreateWsFederationConfigurationImporterAsync(context.ServiceProvider); var relyingPartyImporter = wsFederationConfigurationImporter.Importers.OfType <RelyingPartyImporter>().First(); var result = new DataImportResult(); await relyingPartyImporter.ImportAsync(relyingParties, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, await wsFederationConfigurationImporter.CommitAsync()); } // Test relying-party properties. using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationConfigurationDatabaseContext = context.ServiceProvider.GetRequiredService <IWsFederationConfigurationDbContext>(); var relyingPartyStore = context.ServiceProvider.GetRequiredService <IRelyingPartyStore>(); var relyingPartyEntities = wsFederationConfigurationDatabaseContext.RelyingParties.ToArray(); Assert.AreEqual(3, relyingPartyEntities.Length); foreach (var relyingPartyEntity in relyingPartyEntities) { var relyingParty = await relyingPartyStore.FindRelyingPartyByRealm(relyingPartyEntity.Realm); Assert.AreEqual(relyingParty.ClaimMapping.Count, relyingPartyEntity.ClaimMapping.Count); Assert.AreEqual(relyingParty.DigestAlgorithm, relyingPartyEntity.DigestAlgorithm); Assert.AreEqual(relyingParty.Realm, relyingPartyEntity.Realm); Assert.AreEqual(relyingParty.SamlNameIdentifierFormat, relyingPartyEntity.SamlNameIdentifierFormat); Assert.AreEqual(relyingParty.SignatureAlgorithm, relyingPartyEntity.SignatureAlgorithm); Assert.AreEqual(relyingParty.TokenType, relyingPartyEntity.TokenType); } } foreach (var relyingParty in relyingParties) { if (relyingParty.ClaimMapping != null) { var claimMapping = relyingParty.ClaimMapping.Reverse().ToArray(); relyingParty.ClaimMapping.Clear(); foreach (var item in claimMapping) { relyingParty.ClaimMapping.Add(item.Key, item.Value); } } } // Save changed relying-parties. using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationConfigurationImporter = await this.CreateWsFederationConfigurationImporterAsync(context.ServiceProvider); var relyingPartyImporter = wsFederationConfigurationImporter.Importers.OfType <RelyingPartyImporter>().First(); var result = new DataImportResult(); await relyingPartyImporter.ImportAsync(relyingParties, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, await wsFederationConfigurationImporter.CommitAsync()); } var firstRelyingParty = relyingParties[0]; firstRelyingParty.ClaimMapping.Clear(); firstRelyingParty.ClaimMapping.Add("Key-21", "Value-21"); firstRelyingParty.ClaimMapping.Add("Key-22", "Value-22"); firstRelyingParty.ClaimMapping.Add("Key-23", "Value-23"); // Save changed relying-parties. using (var context = await this.CreateContextAsync(databaseProvider)) { var wsFederationConfigurationImporter = await this.CreateWsFederationConfigurationImporterAsync(context.ServiceProvider); var relyingPartyImporter = wsFederationConfigurationImporter.Importers.OfType <RelyingPartyImporter>().First(); var result = new DataImportResult(); await relyingPartyImporter.ImportAsync(relyingParties, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, ((DbContext)wsFederationConfigurationImporter.DatabaseContext).ChangeTracker.Entries().Count(entry => entry.State == EntityState.Added)); Assert.AreEqual(0, ((DbContext)wsFederationConfigurationImporter.DatabaseContext).ChangeTracker.Entries().Count(entry => entry.State == EntityState.Deleted)); Assert.AreEqual(3, ((DbContext)wsFederationConfigurationImporter.DatabaseContext).ChangeTracker.Entries().Count(entry => entry.State == EntityState.Modified)); Assert.AreEqual(3, await wsFederationConfigurationImporter.CommitAsync()); } }
public async Task ImportAsyncChangesTest(DatabaseProvider databaseProvider) { using (var context = new Context(databaseProvider: databaseProvider)) { context.ApplicationBuilder.UseIdentity(); } using (var context = new Context(databaseProvider: databaseProvider)) { Assert.IsFalse(await context.ServiceProvider.GetRequiredService <IIdentityFacade>().Users.AnyAsync()); } var importOptions = new ImportOptions(); var users = new List <UserModel> { new UserModel { Email = "*****@*****.**", Id = "f6762ef5-d224-437a-9a67-459a9331266c", Password = "******", UserName = "******" }, new UserModel { Email = "*****@*****.**", Id = "efbe866d-d6ba-49cd-875a-36c52aa2339d", Password = "******", UserName = "******" } }; // Save users. using (var context = new Context(databaseProvider: databaseProvider)) { var identityImporter = await this.CreateIdentityImporterAsync(context.ServiceProvider); var userImporter = identityImporter.Importers.OfType <UserImporter>().First(); var result = new DataImportResult(); await userImporter.ImportAsync(users, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(2, await identityImporter.CommitAsync()); } // Test user properties. using (var context = new Context(databaseProvider: databaseProvider)) { var identityFacade = (IdentityFacade)context.ServiceProvider.GetRequiredService <IIdentityFacade>(); var userEntities = identityFacade.Users.ToArray(); Assert.AreEqual(2, userEntities.Length); foreach (var user in users) { var userEntity = await identityFacade.UserManager.FindByIdAsync(user.Id); Assert.AreEqual(user.Email, userEntity.Email); Assert.AreEqual(user.Id, userEntity.Id); Assert.AreEqual(user.UserName, userEntity.UserName); Assert.IsTrue(await identityFacade.UserManager.CheckPasswordAsync(userEntity, user.Password)); } } // Save the same unchanged users again. using (var context = new Context(databaseProvider: databaseProvider)) { var identityImporter = await this.CreateIdentityImporterAsync(context.ServiceProvider); var userImporter = identityImporter.Importers.OfType <UserImporter>().First(); var result = new DataImportResult(); await userImporter.ImportAsync(users, importOptions, result); Assert.IsFalse(result.Errors.Any()); // Even if the properties are not changed, the password must be re-changed. Assert.AreEqual(2, await identityImporter.CommitAsync()); } // Test user properties. using (var context = new Context(databaseProvider: databaseProvider)) { var identityFacade = (IdentityFacade)context.ServiceProvider.GetRequiredService <IIdentityFacade>(); var userEntities = identityFacade.Users.ToArray(); Assert.AreEqual(2, userEntities.Length); foreach (var user in users) { var userEntity = await identityFacade.UserManager.FindByIdAsync(user.Id); Assert.AreEqual(user.Email, userEntity.Email); Assert.AreEqual(user.Id, userEntity.Id); Assert.AreEqual(user.UserName, userEntity.UserName); Assert.IsTrue(await identityFacade.UserManager.CheckPasswordAsync(userEntity, user.Password)); } } foreach (var user in users) { user.Email = $"changed-{user.Email}"; user.Password = $"changed-{user.Password}"; } // Save changed users. using (var context = new Context(databaseProvider: databaseProvider)) { var identityImporter = await this.CreateIdentityImporterAsync(context.ServiceProvider); var userImporter = identityImporter.Importers.OfType <UserImporter>().First(); var result = new DataImportResult(); await userImporter.ImportAsync(users, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(2, await identityImporter.CommitAsync()); } // Test user properties. using (var context = new Context(databaseProvider: databaseProvider)) { var identityFacade = (IdentityFacade)context.ServiceProvider.GetRequiredService <IIdentityFacade>(); var userEntities = identityFacade.Users.ToArray(); Assert.AreEqual(2, userEntities.Length); foreach (var user in users) { var userEntity = await identityFacade.UserManager.FindByIdAsync(user.Id); Assert.AreEqual(user.Email, userEntity.Email); Assert.AreEqual(user.Id, userEntity.Id); Assert.AreEqual(user.UserName, userEntity.UserName); Assert.IsTrue(await identityFacade.UserManager.CheckPasswordAsync(userEntity, user.Password)); } } foreach (var user in users) { user.Email = user.Email.ToUpperInvariant(); user.Password = "******" + user.Password.ToUpperInvariant().Substring(1); user.UserName = user.UserName.ToUpperInvariant(); } // Save changed users. using (var context = new Context(databaseProvider: databaseProvider)) { var identityImporter = await this.CreateIdentityImporterAsync(context.ServiceProvider); var userImporter = identityImporter.Importers.OfType <UserImporter>().First(); var result = new DataImportResult(); await userImporter.ImportAsync(users, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(2, await identityImporter.CommitAsync()); } // Test user properties. using (var context = new Context(databaseProvider: databaseProvider)) { var identityFacade = (IdentityFacade)context.ServiceProvider.GetRequiredService <IIdentityFacade>(); var userEntities = identityFacade.Users.ToArray(); Assert.AreEqual(2, userEntities.Length); foreach (var user in users) { var userEntity = await identityFacade.UserManager.FindByIdAsync(user.Id); Assert.AreEqual(user.Email, userEntity.Email); Assert.AreEqual(user.Id, userEntity.Id); Assert.AreEqual(user.UserName, userEntity.UserName); Assert.IsTrue(await identityFacade.UserManager.CheckPasswordAsync(userEntity, user.Password)); } } var unSavedUsers = new List <UserModel>(); // ReSharper disable ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator foreach (var user in users) { unSavedUsers.Add(new UserModel { Email = $"unsaved-{user.Email}", Id = user.Id, Password = $"unsaved-{user.Password}", UserName = $"unsaved-{user.UserName}" }); } // ReSharper restore ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator // Do not commit for changed users. using (var context = new Context(databaseProvider: databaseProvider)) { var identityImporter = await this.CreateIdentityImporterAsync(context.ServiceProvider); var userImporter = identityImporter.Importers.OfType <UserImporter>().First(); var result = new DataImportResult(); await userImporter.ImportAsync(unSavedUsers, importOptions, result); Assert.IsFalse(result.Errors.Any()); } // Test user properties. using (var context = new Context(databaseProvider: databaseProvider)) { var identityFacade = (IdentityFacade)context.ServiceProvider.GetRequiredService <IIdentityFacade>(); var userEntities = identityFacade.Users.ToArray(); Assert.AreEqual(2, userEntities.Length); foreach (var user in users) { var userEntity = await identityFacade.UserManager.FindByIdAsync(user.Id); Assert.AreEqual(user.Email, userEntity.Email); Assert.AreEqual(user.Id, userEntity.Id); Assert.AreEqual(user.UserName, userEntity.UserName); Assert.IsTrue(await identityFacade.UserManager.CheckPasswordAsync(userEntity, user.Password)); } } }
protected internal virtual async Task ImportAsyncChangesTest(DatabaseProvider databaseProvider) { using (var context = await this.CreateContextAsync(databaseProvider)) { var samlPluginBuilder = context.ServiceProvider.GetRequiredService <ISamlPluginBuilder>(); samlPluginBuilder.Use(context.ApplicationBuilder); } using (var context = await this.CreateContextAsync(databaseProvider)) { Assert.IsFalse(await context.ServiceProvider.GetRequiredService <ISamlConfigurationDbContext>().ServiceProviders.AnyAsync()); } var importOptions = new ImportOptions(); var serviceProviders = new List <ServiceProviderModel> { new ServiceProviderModel { AssertionConsumerServices = { new Service { Binding = "Binding-1", Index = 1, IsDefault = true, Location = "Location-1" }, new Service { Binding = "Binding-2", Index = 2, IsDefault = true, Location = "Location-2" }, new Service { Binding = "Binding-3", Index = 3, IsDefault = true, Location = "Location-3" } }, ClaimsMapping = new Dictionary <string, string> { { "Key-1", "Value-1" }, { "Key-2", "Value-2" }, { "Key-3", "Value-3" } }, EntityId = "Service-provider-1", EncryptionCertificate = await this.GetCertificateAsync(1, true), SigningCertificates = { await this.GetCertificateAsync(1, true), await this.GetCertificateAsync(2), await this.GetCertificateAsync(3) }, SingleLogoutServices = { new Service { Binding = "Binding-1", Index = 1, IsDefault = true, Location = "Location-1" }, new Service { Binding = "Binding-2", Index = 2, IsDefault = true, Location = "Location-2" }, new Service { Binding = "Binding-3", Index = 3, IsDefault = true, Location = "Location-3" } } }, new ServiceProviderModel { EntityId = "Service-provider-2", EncryptionCertificate = await this.GetCertificateAsync(2), SigningCertificates = { await this.GetCertificateAsync(1, true), await this.GetCertificateAsync(2) } }, new ServiceProviderModel { EntityId = "Service-provider-3", EncryptionCertificate = await this.GetCertificateAsync(3) } }; // Test certificates. Assert.IsTrue(serviceProviders[0].EncryptionCertificate.HasPrivateKey); Assert.IsFalse(serviceProviders[1].EncryptionCertificate.HasPrivateKey); Assert.IsFalse(serviceProviders[2].EncryptionCertificate.HasPrivateKey); // Save service-providers. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationImporter = await this.CreateSamlConfigurationImporterAsync(context.ServiceProvider); var serviceProviderImporter = samlConfigurationImporter.Importers.OfType <ServiceProviderImporter>().First(); var result = new DataImportResult(); await serviceProviderImporter.ImportAsync(serviceProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(17, await samlConfigurationImporter.CommitAsync()); } // Test service-provider properties. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationDatabaseContext = context.ServiceProvider.GetRequiredService <ISamlConfigurationDbContext>(); var serviceProviderStore = context.ServiceProvider.GetRequiredService <IServiceProviderStore>(); var serviceProviderEntities = samlConfigurationDatabaseContext.ServiceProviders.ToArray(); Assert.AreEqual(3, serviceProviderEntities.Length); foreach (var serviceProviderEntity in serviceProviderEntities) { var serviceProviderModel = await serviceProviderStore.FindServiceProviderByEntityId(serviceProviderEntity.EntityId); Assert.AreEqual(serviceProviderModel.AllowIdpInitiatedSso, serviceProviderEntity.AllowIdpInitiatedSso); Assert.AreEqual(serviceProviderModel.AssertionConsumerServices.Count, serviceProviderEntity.AssertionConsumerServices.Count); Assert.AreEqual(serviceProviderModel.ClaimsMapping.Count, serviceProviderEntity.ClaimsMapping.Count); Assert.AreEqual(serviceProviderModel.EncryptAssertions, serviceProviderEntity.EncryptAssertions); Assert.AreEqual(Convert.ToBase64String(serviceProviderModel.EncryptionCertificate.GetRawCertData()), Convert.ToBase64String(serviceProviderEntity.EncryptionCertificate)); Assert.IsFalse(serviceProviderModel.EncryptionCertificate.HasPrivateKey); Assert.AreEqual(serviceProviderModel.EntityId, serviceProviderEntity.EntityId); Assert.AreEqual(serviceProviderModel.RequireAuthenticationRequestsSigned, serviceProviderEntity.RequireAuthenticationRequestsSigned); Assert.AreEqual(serviceProviderModel.SignAssertions, serviceProviderEntity.SignAssertions); Assert.AreEqual(serviceProviderModel.SigningCertificates.Count, serviceProviderEntity.SigningCertificates.Count); Assert.IsFalse(serviceProviderModel.SigningCertificates.Any(signingCertificate => signingCertificate.HasPrivateKey)); Assert.AreEqual(serviceProviderModel.SingleLogoutServices.Count, serviceProviderEntity.SingleLogoutServices.Count); } } // Save the same unchanged service-providers again. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationImporter = await this.CreateSamlConfigurationImporterAsync(context.ServiceProvider); var serviceProviderImporter = samlConfigurationImporter.Importers.OfType <ServiceProviderImporter>().First(); var result = new DataImportResult(); await serviceProviderImporter.ImportAsync(serviceProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, await samlConfigurationImporter.CommitAsync()); } // Test service-provider properties. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationDatabaseContext = context.ServiceProvider.GetRequiredService <ISamlConfigurationDbContext>(); var serviceProviderStore = context.ServiceProvider.GetRequiredService <IServiceProviderStore>(); var serviceProviderEntities = samlConfigurationDatabaseContext.ServiceProviders.ToArray(); Assert.AreEqual(3, serviceProviderEntities.Length); foreach (var serviceProviderEntity in serviceProviderEntities) { var serviceProviderModel = await serviceProviderStore.FindServiceProviderByEntityId(serviceProviderEntity.EntityId); Assert.AreEqual(serviceProviderModel.AllowIdpInitiatedSso, serviceProviderEntity.AllowIdpInitiatedSso); Assert.AreEqual(serviceProviderModel.AssertionConsumerServices.Count, serviceProviderEntity.AssertionConsumerServices.Count); Assert.AreEqual(serviceProviderModel.ClaimsMapping.Count, serviceProviderEntity.ClaimsMapping.Count); Assert.AreEqual(serviceProviderModel.EncryptAssertions, serviceProviderEntity.EncryptAssertions); Assert.AreEqual(Convert.ToBase64String(serviceProviderModel.EncryptionCertificate.GetRawCertData()), Convert.ToBase64String(serviceProviderEntity.EncryptionCertificate)); Assert.IsFalse(serviceProviderModel.EncryptionCertificate.HasPrivateKey); Assert.AreEqual(serviceProviderModel.EntityId, serviceProviderEntity.EntityId); Assert.AreEqual(serviceProviderModel.RequireAuthenticationRequestsSigned, serviceProviderEntity.RequireAuthenticationRequestsSigned); Assert.AreEqual(serviceProviderModel.SignAssertions, serviceProviderEntity.SignAssertions); Assert.AreEqual(serviceProviderModel.SigningCertificates.Count, serviceProviderEntity.SigningCertificates.Count); Assert.IsFalse(serviceProviderModel.SigningCertificates.Any(signingCertificate => signingCertificate.HasPrivateKey)); Assert.AreEqual(serviceProviderModel.SingleLogoutServices.Count, serviceProviderEntity.SingleLogoutServices.Count); } } foreach (var serviceProvider in serviceProviders) { serviceProvider.AssertionConsumerServices.Reverse(); serviceProvider.SigningCertificates.Reverse(); serviceProvider.SingleLogoutServices.Reverse(); if (serviceProvider.ClaimsMapping != null) { var claimsMapping = serviceProvider.ClaimsMapping.Reverse().ToArray(); serviceProvider.ClaimsMapping.Clear(); foreach (var item in claimsMapping) { serviceProvider.ClaimsMapping.Add(item); } } } // Save changed service-providers. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationImporter = await this.CreateSamlConfigurationImporterAsync(context.ServiceProvider); var serviceProviderImporter = samlConfigurationImporter.Importers.OfType <ServiceProviderImporter>().First(); var result = new DataImportResult(); await serviceProviderImporter.ImportAsync(serviceProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, await samlConfigurationImporter.CommitAsync()); } serviceProviders[0].AssertionConsumerServices.First(item => item.Index == 2).Index = 22; serviceProviders[0].AssertionConsumerServices.First(item => item.Index == 3).Index = 23; // Save changed service-providers. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationImporter = await this.CreateSamlConfigurationImporterAsync(context.ServiceProvider); var serviceProviderImporter = samlConfigurationImporter.Importers.OfType <ServiceProviderImporter>().First(); var result = new DataImportResult(); await serviceProviderImporter.ImportAsync(serviceProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(2, await samlConfigurationImporter.CommitAsync()); } //// Test service-provider properties. //using(var context = await this.CreateContextAsync(databaseProvider)) //{ // var samlConfigurationDatabaseContext = context.ServiceProvider.GetRequiredService<ISamlConfigurationDbContext>(); // var serviceProviderStore = context.ServiceProvider.GetRequiredService<IServiceProviderStore>(); // var serviceProviderEntities = samlConfigurationDatabaseContext.ServiceProviders.ToArray(); // foreach(var serviceProviderEntity in serviceProviderEntities) // { // var serviceProviderModel = await serviceProviderStore.FindServiceProviderByEntityId(serviceProviderEntity.EntityId); // // Do asserts. // } //} var firstServiceProvider = serviceProviders[0]; firstServiceProvider.AssertionConsumerServices.Clear(); firstServiceProvider.AssertionConsumerServices.AddRange(new[] { new Service { Binding = "Binding-21", Index = 21, IsDefault = true, Location = "Location-21" }, new Service { Binding = "Binding-22", Index = 22, IsDefault = true, Location = "Location-22" }, new Service { Binding = "Binding-23", Index = 23, IsDefault = true, Location = "Location-23" } }); firstServiceProvider.ClaimsMapping.Clear(); firstServiceProvider.ClaimsMapping = new Dictionary <string, string> { { "Key-21", "Value-21" }, { "Key-22", "Value-22" }, { "Key-23", "Value-23" } }; firstServiceProvider.SigningCertificates.Clear(); firstServiceProvider.SigningCertificates.AddRange(new[] { await this.GetCertificateAsync(3), await this.GetCertificateAsync(2) }); firstServiceProvider.SingleLogoutServices.Clear(); firstServiceProvider.SingleLogoutServices.AddRange(new[] { new Service { Binding = "Binding-21", Index = 21, IsDefault = true, Location = "Location-21" }, new Service { Binding = "Binding-22", Index = 22, IsDefault = true, Location = "Location-22" }, new Service { Binding = "Binding-23", Index = 23, IsDefault = true, Location = "Location-23" } }); // Save changed service-providers. using (var context = await this.CreateContextAsync(databaseProvider)) { var samlConfigurationImporter = await this.CreateSamlConfigurationImporterAsync(context.ServiceProvider); var serviceProviderImporter = samlConfigurationImporter.Importers.OfType <ServiceProviderImporter>().First(); var result = new DataImportResult(); await serviceProviderImporter.ImportAsync(serviceProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, ((DbContext)samlConfigurationImporter.DatabaseContext).ChangeTracker.Entries().Count(entry => entry.State == EntityState.Added)); Assert.AreEqual(1, ((DbContext)samlConfigurationImporter.DatabaseContext).ChangeTracker.Entries().Count(entry => entry.State == EntityState.Deleted)); Assert.AreEqual(9, ((DbContext)samlConfigurationImporter.DatabaseContext).ChangeTracker.Entries().Count(entry => entry.State == EntityState.Modified)); Assert.AreEqual(10, await samlConfigurationImporter.CommitAsync()); } //// Test service-provider properties. //using(var context = await this.CreateContextAsync(databaseProvider)) //{ // var samlConfigurationDatabaseContext = context.ServiceProvider.GetRequiredService<ISamlConfigurationDbContext>(); // var serviceProviderStore = context.ServiceProvider.GetRequiredService<IServiceProviderStore>(); // var serviceProviderEntities = samlConfigurationDatabaseContext.ServiceProviders.ToArray(); // foreach(var serviceProviderEntity in serviceProviderEntities) // { // var serviceProviderModel = await serviceProviderStore.FindServiceProviderByEntityId(serviceProviderEntity.EntityId); // // Do asserts. // } //} }
public async Task ImportAsyncChangesTest(DatabaseProvider databaseProvider, bool dynamicAuthenticationProvidersFeatureEnabled) { using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { context.ApplicationBuilder.UseIdentityServer(); } using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { Assert.IsFalse(await context.ServiceProvider.GetRequiredService <IConfigurationDbContext>().IdentityProviders.AnyAsync()); } var importOptions = new ImportOptions(); var identityProviders = new List <IdentityProvider> { new OidcProvider { Properties = { { "First-property", "First-property-value" }, { "Second-property", "Second-property-value" } }, Scheme = "Scheme-1" }, new OidcProvider { Scheme = "Scheme-2" } }; // Save identity-providers. using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { var configurationImporter = await this.CreateConfigurationImporterAsync(context.ServiceProvider); var identityProviderImporter = configurationImporter.Importers.OfType <IdentityProviderImporter>().First(); var result = new DataImportResult(); await identityProviderImporter.ImportAsync(identityProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(2, await configurationImporter.CommitAsync()); } // Test identity-provider properties. using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { if (dynamicAuthenticationProvidersFeatureEnabled) { this.FakeHttpContextIfNecessary(context); var identityProviderStore = context.ServiceProvider.GetRequiredService <IIdentityProviderStore>(); var identityProviderNames = (await identityProviderStore.GetAllSchemeNamesAsync()).ToArray(); Assert.AreEqual(2, identityProviderNames.Length); IdentityProvider identityProvider; foreach (var identityProviderName in identityProviderNames) { identityProvider = await identityProviderStore.GetBySchemeAsync(identityProviderName.Scheme); Assert.AreEqual(identityProviderName.DisplayName, identityProvider.DisplayName); Assert.AreEqual(identityProviderName.Enabled, identityProvider.Enabled); Assert.AreEqual(identityProviderName.Scheme, identityProvider.Scheme); } identityProvider = await identityProviderStore.GetBySchemeAsync("Scheme-1"); Assert.AreEqual(2, identityProvider.Properties.Count); identityProvider = await identityProviderStore.GetBySchemeAsync("Scheme-2"); Assert.AreEqual(0, identityProvider.Properties.Count); } } // Save the same unchanged identity-providers again. using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { var configurationImporter = await this.CreateConfigurationImporterAsync(context.ServiceProvider); var identityProviderImporter = configurationImporter.Importers.OfType <IdentityProviderImporter>().First(); var result = new DataImportResult(); await identityProviderImporter.ImportAsync(identityProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(0, await configurationImporter.CommitAsync()); } foreach (var identityProvider in identityProviders) { identityProvider.Properties.Add("New-property", "New-property-value"); } // Save changed identity-providers. using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { var configurationImporter = await this.CreateConfigurationImporterAsync(context.ServiceProvider); var identityProviderImporter = configurationImporter.Importers.OfType <IdentityProviderImporter>().First(); var result = new DataImportResult(); await identityProviderImporter.ImportAsync(identityProviders, importOptions, result); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(2, await configurationImporter.CommitAsync()); } // Test identity-provider properties. using (var context = this.CreateContext(databaseProvider, dynamicAuthenticationProvidersFeatureEnabled)) { if (dynamicAuthenticationProvidersFeatureEnabled) { this.FakeHttpContextIfNecessary(context); var identityProviderStore = context.ServiceProvider.GetRequiredService <IIdentityProviderStore>(); var identityProviderNames = (await identityProviderStore.GetAllSchemeNamesAsync()).ToArray(); Assert.AreEqual(2, identityProviderNames.Length); IdentityProvider identityProvider; foreach (var identityProviderName in identityProviderNames) { identityProvider = await identityProviderStore.GetBySchemeAsync(identityProviderName.Scheme); Assert.AreEqual(identityProviderName.DisplayName, identityProvider.DisplayName); Assert.AreEqual(identityProviderName.Enabled, identityProvider.Enabled); Assert.AreEqual(identityProviderName.Scheme, identityProvider.Scheme); } identityProvider = await identityProviderStore.GetBySchemeAsync("Scheme-1"); Assert.AreEqual(3, identityProvider.Properties.Count); identityProvider = await identityProviderStore.GetBySchemeAsync("Scheme-2"); Assert.AreEqual(1, identityProvider.Properties.Count); } } }
protected internal virtual async Task ImportAsyncScenarioTest(ImportOptions importOptions, IList <ClientModel> models, int savedChangesExpected, IServiceProvider serviceProvider) { if (importOptions == null) { throw new ArgumentNullException(nameof(importOptions)); } if (models == null) { throw new ArgumentNullException(nameof(models)); } if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } using (var serviceScope = serviceProvider.CreateScope()) { var clientStore = serviceScope.ServiceProvider.GetRequiredService <IClientStore>(); var configurationDatabaseContext = serviceScope.ServiceProvider.GetRequiredService <IConfigurationDbContext>(); var clientImporter = await this.CreateClientImporterAsync(configurationDatabaseContext, serviceScope.ServiceProvider); var result = new DataImportResult(); await clientImporter.ImportAsync(models, importOptions, result); var savedChanges = await configurationDatabaseContext.SaveChangesAsync(); Assert.IsFalse(result.Errors.Any()); Assert.AreEqual(savedChangesExpected, savedChanges); foreach (var model in models) { var client = await clientStore.FindClientByIdAsync(model.ClientId); Assert.AreEqual(model.Description, client.Description); Assert.AreEqual(model.AllowedGrantTypes.Count, client.AllowedGrantTypes.Count); for (var i = 0; i < model.AllowedGrantTypes.Count; i++) { Assert.AreEqual(model.AllowedGrantTypes.ElementAt(i), client.AllowedGrantTypes.ElementAt(i)); } Assert.AreEqual(model.ClientSecrets.Count, client.ClientSecrets.Count); for (var i = 0; i < model.ClientSecrets.Count; i++) { Assert.AreEqual(model.ClientSecrets.ElementAt(i).Description, client.ClientSecrets.ElementAt(i).Description); Assert.AreEqual(model.ClientSecrets.ElementAt(i).Expiration, client.ClientSecrets.ElementAt(i).Expiration); Assert.AreEqual(model.ClientSecrets.ElementAt(i).Type, client.ClientSecrets.ElementAt(i).Type); Assert.AreEqual(model.ClientSecrets.ElementAt(i).Value, client.ClientSecrets.ElementAt(i).Value); } } } using (var serviceScope = serviceProvider.CreateScope()) { var configurationDatabaseContext = serviceScope.ServiceProvider.GetRequiredService <IConfigurationDbContext>(); Assert.AreEqual(configurationDatabaseContext.ClientClaims().Count(), models.SelectMany(client => client.Claims).Count()); Assert.AreEqual(configurationDatabaseContext.ClientGrantTypes().Count(), models.SelectMany(client => client.AllowedGrantTypes).Count()); Assert.AreEqual(configurationDatabaseContext.ClientIdentityProviderRestrictions().Count(), models.SelectMany(client => client.IdentityProviderRestrictions).Count()); Assert.AreEqual(configurationDatabaseContext.ClientPostLogoutRedirectUris().Count(), models.SelectMany(client => client.PostLogoutRedirectUris).Count()); Assert.AreEqual(configurationDatabaseContext.ClientProperties().Count(), models.SelectMany(client => client.Properties).Count()); Assert.AreEqual(configurationDatabaseContext.ClientRedirectUris().Count(), models.SelectMany(client => client.RedirectUris).Count()); Assert.AreEqual(configurationDatabaseContext.ClientSecrets().Count(), models.SelectMany(client => client.ClientSecrets).Count()); Assert.AreEqual(configurationDatabaseContext.ClientScopes().Count(), models.SelectMany(client => client.AllowedScopes).Count()); } }