Feature #42: Active Directory Interop Upgrade
AD Interop moved to Disco.Services; Supports multi-domain environments, sites, and searching restricted with OUs.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using Disco.Data.Repository;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Data.Configuration.Modules
|
||||
{
|
||||
public class ActiveDirectoryConfiguration : ConfigurationBase
|
||||
{
|
||||
public ActiveDirectoryConfiguration(DiscoDataContext Database) : base(Database) { }
|
||||
|
||||
public override string Scope
|
||||
{
|
||||
get { return "ActiveDirectory"; }
|
||||
}
|
||||
|
||||
public List<string> SearchContainers
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetFromJson<List<string>>(null);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAsJson(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool? SearchEntireForest
|
||||
{
|
||||
get { return GetFromJson<bool?>(null); }
|
||||
set { SetAsJson(value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ namespace Disco.Data.Configuration
|
||||
this.moduleDeviceProfilesConfiguration = new Lazy<Modules.DeviceProfilesConfiguration>(() => new Modules.DeviceProfilesConfiguration(Database));
|
||||
this.moduleOrganisationAddressesConfiguration = new Lazy<Modules.OrganisationAddressesConfiguration>(() => new Modules.OrganisationAddressesConfiguration(Database));
|
||||
this.moduleJobPreferencesConfiguration = new Lazy<Modules.JobPreferencesConfiguration>(() => new Modules.JobPreferencesConfiguration(Database));
|
||||
this.moduleActiveDirectoryConfiguration = new Lazy<Modules.ActiveDirectoryConfiguration>(() => new Modules.ActiveDirectoryConfiguration(Database));
|
||||
}
|
||||
|
||||
#region Configuration Modules
|
||||
@@ -29,6 +30,7 @@ namespace Disco.Data.Configuration
|
||||
private Lazy<Modules.DeviceProfilesConfiguration> moduleDeviceProfilesConfiguration;
|
||||
private Lazy<Modules.OrganisationAddressesConfiguration> moduleOrganisationAddressesConfiguration;
|
||||
private Lazy<Modules.JobPreferencesConfiguration> moduleJobPreferencesConfiguration;
|
||||
private Lazy<Modules.ActiveDirectoryConfiguration> moduleActiveDirectoryConfiguration;
|
||||
|
||||
public Modules.BootstrapperConfiguration Bootstrapper
|
||||
{
|
||||
@@ -58,6 +60,13 @@ namespace Disco.Data.Configuration
|
||||
return moduleJobPreferencesConfiguration.Value;
|
||||
}
|
||||
}
|
||||
public Modules.ActiveDirectoryConfiguration ActiveDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return moduleActiveDirectoryConfiguration.Value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.Entity" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Reactive.Core">
|
||||
<HintPath>..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll</HintPath>
|
||||
@@ -72,6 +73,7 @@
|
||||
<Compile Include="Configuration\CommunityHelpers.cs" />
|
||||
<Compile Include="Configuration\ConfigurationBase.cs" />
|
||||
<Compile Include="Configuration\ConfigurationCache.cs" />
|
||||
<Compile Include="Configuration\Modules\ActiveDirectoryConfiguration.cs" />
|
||||
<Compile Include="Configuration\Modules\JobPreferencesConfiguration.cs" />
|
||||
<Compile Include="Configuration\SystemConfiguration.cs" />
|
||||
<Compile Include="Configuration\Modules\BootstrapperConfiguration.cs" />
|
||||
@@ -130,6 +132,10 @@
|
||||
<Compile Include="Migrations\201402032322432_DBv12.Designer.cs">
|
||||
<DependentUpon>201402032322432_DBv12.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Migrations\201404080227546_DBv13.cs" />
|
||||
<Compile Include="Migrations\201404080227546_DBv13.Designer.cs">
|
||||
<DependentUpon>201404080227546_DBv13.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Migrations\Configuration.cs" />
|
||||
<Compile Include="Migrations\DiscoDataMigrator.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -181,6 +187,9 @@
|
||||
<EmbeddedResource Include="Migrations\201402032322432_DBv12.resx">
|
||||
<DependentUpon>201402032322432_DBv12.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Migrations\201404080227546_DBv13.resx">
|
||||
<DependentUpon>201404080227546_DBv13.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// <auto-generated />
|
||||
namespace Disco.Data.Migrations
|
||||
{
|
||||
using System.Data.Entity.Migrations;
|
||||
using System.Data.Entity.Migrations.Infrastructure;
|
||||
using System.Resources;
|
||||
|
||||
public sealed partial class DBv13 : IMigrationMetadata
|
||||
{
|
||||
private readonly ResourceManager Resources = new ResourceManager(typeof(DBv13));
|
||||
|
||||
string IMigrationMetadata.Id
|
||||
{
|
||||
get { return "201404080227546_DBv13"; }
|
||||
}
|
||||
|
||||
string IMigrationMetadata.Source
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
string IMigrationMetadata.Target
|
||||
{
|
||||
get { return Resources.GetString("Target"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Disco.Data.Migrations
|
||||
{
|
||||
using System;
|
||||
using System.Data.Entity.Migrations;
|
||||
|
||||
public partial class DBv13 : DbMigration
|
||||
{
|
||||
public override void Up()
|
||||
{
|
||||
AlterColumn("dbo.Devices", "ComputerName", c => c.String(maxLength: 50));
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
AlterColumn("dbo.Devices", "ComputerName", c => c.String(maxLength: 24));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -3,6 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Disco.Models.Repository;
|
||||
using System.Data.SqlClient;
|
||||
using System.DirectoryServices.ActiveDirectory;
|
||||
using System.DirectoryServices;
|
||||
|
||||
namespace Disco.Data.Repository
|
||||
{
|
||||
@@ -15,6 +18,9 @@ namespace Disco.Data.Repository
|
||||
Database.SeedDeviceProfiles();
|
||||
Database.SeedJobTypes();
|
||||
Database.SeedJobSubTypes();
|
||||
|
||||
// Migration Maintenance
|
||||
Database.MigratePreDomainObjects();
|
||||
}
|
||||
|
||||
public static void SeedDeploymentId(this DiscoDataContext Database)
|
||||
@@ -304,5 +310,128 @@ namespace Disco.Data.Repository
|
||||
}
|
||||
}
|
||||
// End Added: 2013-02-07 G#
|
||||
|
||||
#region Migrate Users SQL
|
||||
private const string MigratePreDomainUsers_Sql = @"INSERT INTO [Users] SELECT @IdNew, u.DisplayName, u.Surname, u.GivenName, u.PhoneNumber, u.EmailAddress FROM [Users] u WHERE [Id]=@IdExisting;
|
||||
|
||||
UPDATE [JobQueueJobs] SET [AddedUserId]=@IdNew WHERE [AddedUserId]=@IdExisting;
|
||||
UPDATE [JobQueueJobs] SET [RemovedUserId]=@IdNew WHERE [RemovedUserId]=@IdExisting;
|
||||
|
||||
UPDATE [DeviceAttachments] SET [TechUserId]=@IdNew WHERE [TechUserId]=@IdExisting;
|
||||
|
||||
UPDATE [Devices] SET [AssignedUserId]=@IdNew WHERE [AssignedUserId]=@IdExisting;
|
||||
|
||||
UPDATE [DeviceUserAssignments] SET [AssignedUserId]=@IdNew WHERE [AssignedUserId]=@IdExisting;
|
||||
|
||||
UPDATE [JobAttachments] SET [TechUserId]=@IdNew WHERE [TechUserId]=@IdExisting;
|
||||
|
||||
UPDATE [JobComponents] SET [TechUserId]=@IdNew WHERE [TechUserId]=@IdExisting;
|
||||
|
||||
UPDATE [JobLogs] SET [TechUserId]=@IdNew WHERE [TechUserId]=@IdExisting;
|
||||
|
||||
UPDATE [JobMetaInsurances] SET [ClaimFormSentUserId]=@IdNew WHERE [ClaimFormSentUserId]=@IdExisting;
|
||||
|
||||
UPDATE [JobMetaNonWarranties] SET [AccountingChargeAddedUserId]=@IdNew WHERE [AccountingChargeAddedUserId]=@IdExisting;
|
||||
UPDATE [JobMetaNonWarranties] SET [AccountingChargePaidUserId]=@IdNew WHERE [AccountingChargePaidUserId]=@IdExisting;
|
||||
UPDATE [JobMetaNonWarranties] SET [AccountingChargeRequiredUserId]=@IdNew WHERE [AccountingChargeRequiredUserId]=@IdExisting;
|
||||
UPDATE [JobMetaNonWarranties] SET [InvoiceReceivedUserId]=@IdNew WHERE [InvoiceReceivedUserId]=@IdExisting;
|
||||
UPDATE [JobMetaNonWarranties] SET [PurchaseOrderRaisedUserId]=@IdNew WHERE [PurchaseOrderRaisedUserId]=@IdExisting;
|
||||
UPDATE [JobMetaNonWarranties] SET [PurchaseOrderSentUserId]=@IdNew WHERE [PurchaseOrderSentUserId]=@IdExisting;
|
||||
|
||||
UPDATE [Jobs] SET [ClosedTechUserId]=@IdNew WHERE [ClosedTechUserId]=@IdExisting;
|
||||
UPDATE [Jobs] SET [DeviceHeldTechUserId]=@IdNew WHERE [DeviceHeldTechUserId]=@IdExisting;
|
||||
UPDATE [Jobs] SET [DeviceReadyForReturnTechUserId]=@IdNew WHERE [DeviceReadyForReturnTechUserId]=@IdExisting;
|
||||
UPDATE [Jobs] SET [DeviceReturnedTechUserId]=@IdNew WHERE [DeviceReturnedTechUserId]=@IdExisting;
|
||||
UPDATE [Jobs] SET [OpenedTechUserId]=@IdNew WHERE [OpenedTechUserId]=@IdExisting;
|
||||
UPDATE [Jobs] SET [UserId]=@IdNew WHERE [UserId]=@IdExisting;
|
||||
|
||||
UPDATE [UserAttachments] SET [TechUserId]=@IdNew WHERE [TechUserId]=@IdExisting;
|
||||
UPDATE [UserAttachments] SET [UserId]=@IdNew WHERE [UserId]=@IdExisting;
|
||||
|
||||
DELETE [Users] WHERE [Id]=@IdExisting;";
|
||||
#endregion
|
||||
public static void MigratePreDomainObjects(this DiscoDataContext Database)
|
||||
{
|
||||
if (Database.Users.Count(u => !u.UserId.Contains(@"\")) > 0)
|
||||
{
|
||||
// Determine Computer Domain
|
||||
string netBiosName = null;
|
||||
string defaultNamingContext;
|
||||
using (Domain d = Domain.GetComputerDomain())
|
||||
{
|
||||
string ldapPath = string.Format("LDAP://{0}/", d.Name);
|
||||
string configurationNamingContext;
|
||||
|
||||
using (var adRootDSE = new DirectoryEntry(ldapPath + "RootDSE"))
|
||||
{
|
||||
defaultNamingContext = adRootDSE.Properties["defaultNamingContext"][0].ToString();
|
||||
configurationNamingContext = adRootDSE.Properties["configurationNamingContext"][0].ToString();
|
||||
}
|
||||
|
||||
using (var configSearchRoot = new DirectoryEntry(ldapPath + "CN=Partitions," + configurationNamingContext))
|
||||
{
|
||||
var configSearchFilter = string.Format("(&(objectcategory=Crossref)(dnsRoot={0})(netBIOSName=*))", d.Name);
|
||||
var configSearchLoadProperites = new string[] { "NetBIOSName" };
|
||||
|
||||
using (var configSearcher = new DirectorySearcher(configSearchRoot, configSearchFilter, configSearchLoadProperites, SearchScope.OneLevel))
|
||||
{
|
||||
SearchResult configResult = configSearcher.FindOne();
|
||||
|
||||
if (configResult != null)
|
||||
netBiosName = configResult.Properties["NetBIOSName"][0].ToString();
|
||||
else
|
||||
netBiosName = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(netBiosName))
|
||||
throw new InvalidOperationException("Unable to determine the Domains NetBIOS Name");
|
||||
|
||||
// MIGRATE SETTINGS
|
||||
|
||||
// Authorization Roles
|
||||
foreach (var authRole in Database.AuthorizationRoles.Where(ar => ar.SubjectIds != null).ToList())
|
||||
{
|
||||
var ids = string.Join(",", authRole.SubjectIds.Split(',').Select(id => id.Contains('\\') ? id : string.Format("{0}\\{1}", netBiosName, id)));
|
||||
if (ids != authRole.SubjectIds)
|
||||
authRole.SubjectIds = ids;
|
||||
}
|
||||
// Job Queues
|
||||
foreach (var jobQueue in Database.JobQueues.Where(jq => jq.SubjectIds != null).ToList())
|
||||
{
|
||||
var ids = string.Join(",", jobQueue.SubjectIds.Split(',').Select(id => id.Contains('\\') ? id : string.Format("{0}\\{1}", netBiosName, id)));
|
||||
if (ids != jobQueue.SubjectIds)
|
||||
jobQueue.SubjectIds = ids;
|
||||
}
|
||||
// Device Profiles - OU
|
||||
foreach (var deviceProfile in Database.DeviceProfiles.Where(dp => dp.OrganisationalUnit == null || !dp.OrganisationalUnit.Contains(@"DC=")).ToList())
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(deviceProfile.OrganisationalUnit))
|
||||
deviceProfile.OrganisationalUnit = string.Format("CN=Computers,{0}", defaultNamingContext);
|
||||
else
|
||||
deviceProfile.OrganisationalUnit = string.Format("{0},{1}", deviceProfile.OrganisationalUnit, defaultNamingContext);
|
||||
}
|
||||
Database.SaveChanges();
|
||||
|
||||
// MIGRATE DEVICES
|
||||
foreach (var device in Database.Devices.Where(d => d.DeviceDomainId != null && !d.DeviceDomainId.Contains(@"\")).ToList())
|
||||
{
|
||||
device.DeviceDomainId = string.Format("{0}\\{1}", netBiosName, device.DeviceDomainId);
|
||||
}
|
||||
Database.SaveChanges();
|
||||
|
||||
// MIGRATE USERS
|
||||
foreach (var user in Database.Users.Where(u => !u.UserId.Contains(@"\")).ToList())
|
||||
{
|
||||
SqlParameter idExisting = new SqlParameter("@IdExisting", System.Data.SqlDbType.NVarChar, 50);
|
||||
idExisting.Value = user.UserId;
|
||||
|
||||
SqlParameter idNew = new SqlParameter("@IdNew", System.Data.SqlDbType.NVarChar, 50);
|
||||
idNew.Value = string.Format("{0}\\{1}", netBiosName, user.UserId);
|
||||
|
||||
Database.Database.ExecuteSqlCommand(MigratePreDomainUsers_Sql, idExisting, idNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user