Files
Disco/Disco.Services/Devices/ManagedGroups/DeviceProfileDevicesManagedGroup.cs
2017-03-25 15:29:51 +11:00

188 lines
7.8 KiB
C#

using Disco.Data.Repository;
using Disco.Data.Repository.Monitor;
using Disco.Models.Repository;
using Disco.Models.Services.Interop.ActiveDirectory;
using Disco.Services.Interop.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
namespace Disco.Services.Devices.ManagedGroups
{
public class DeviceProfileDevicesManagedGroup : ADManagedGroup
{
private const string KeyFormat = "DeviceProfile_{0}_Devices";
private const string DescriptionFormat = "Devices within the {0} Profile will be added to this Active Directory group.";
private const string CategoryDescriptionFormat = "Devices Linked Group";
private const string GroupDescriptionFormat = "{0} [Device Profile Devices]";
private static Lazy<IObservable<RepositoryMonitorEvent>> RepositoryEvents;
private IDisposable repositorySubscription;
private int DeviceProfileId;
private string DeviceProfileName;
public override string Description { get { return string.Format(DescriptionFormat, DeviceProfileName); } }
public override string CategoryDescription { get { return CategoryDescriptionFormat; } }
public override string GroupDescription { get { return string.Format(GroupDescriptionFormat, DeviceProfileName); } }
public override bool IncludeFilterBeginDate { get { return false; } }
static DeviceProfileDevicesManagedGroup()
{
RepositoryEvents =
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
RepositoryMonitor.StreamBeforeCommit.Where(e =>
e.EntityType == typeof(Device) && (
(e.EventType == RepositoryMonitorEventType.Added &&
ActiveDirectory.IsValidDomainAccountId(((Device)e.Entity).DeviceDomainId)) ||
(e.EventType == RepositoryMonitorEventType.Modified &&
(e.ModifiedProperties.Contains("DeviceProfileId") || e.ModifiedProperties.Contains("DeviceDomainId") || e.ModifiedProperties.Contains("LastEnrolDate"))) ||
(e.EventType == RepositoryMonitorEventType.Deleted)
)
));
}
private DeviceProfileDevicesManagedGroup(string Key, ADManagedGroupConfiguration Configuration, DeviceProfile DeviceProfile)
: base(Key, Configuration)
{
DeviceProfileId = DeviceProfile.Id;
DeviceProfileName = DeviceProfile.Name;
}
public override void Initialize()
{
// Subscribe to changes
repositorySubscription = RepositoryEvents.Value
.Where(e =>
(((Device)e.Entity).DeviceProfileId == DeviceProfileId) ||
(e.EventType == RepositoryMonitorEventType.Modified && e.GetPreviousPropertyValue<int>("DeviceProfileId") == DeviceProfileId))
.Subscribe(ProcessRepositoryEvent);
}
public static string GetKey(DeviceProfile DeviceProfile)
{
return string.Format(KeyFormat, DeviceProfile.Id);
}
public static string GetDescription(DeviceProfile DeviceProfile)
{
return string.Format(DescriptionFormat, DeviceProfile.Name);
}
public static string GetCategoryDescription(DeviceProfile DeviceProfile)
{
return CategoryDescriptionFormat;
}
public static bool TryGetManagedGroup(DeviceProfile DeviceProfile, out DeviceProfileDevicesManagedGroup ManagedGroup)
{
ADManagedGroup managedGroup;
string key = GetKey(DeviceProfile);
if (ActiveDirectory.Context.ManagedGroups.TryGetValue(key, out managedGroup))
{
ManagedGroup = (DeviceProfileDevicesManagedGroup)managedGroup;
return true;
}
else
{
ManagedGroup = null;
return false;
}
}
public static DeviceProfileDevicesManagedGroup Initialize(DeviceProfile DeviceProfile)
{
if (DeviceProfile.Id > 0)
{
var key = GetKey(DeviceProfile);
if (!string.IsNullOrEmpty(DeviceProfile.DevicesLinkedGroup))
{
var config = ADManagedGroup.ConfigurationFromJson(DeviceProfile.DevicesLinkedGroup);
if (config != null && !string.IsNullOrWhiteSpace(config.GroupId))
{
var group = new DeviceProfileDevicesManagedGroup(
key,
config,
DeviceProfile);
// Add to AD Context
ActiveDirectory.Context.ManagedGroups.AddOrUpdate(group);
return group;
}
}
// Remove from AD Context
ActiveDirectory.Context.ManagedGroups.Remove(key);
}
return null;
}
public override IEnumerable<string> DetermineMembers(DiscoDataContext Database)
{
return Database.Devices
.Where(d => d.DeviceProfileId == DeviceProfileId)
.Where(d => d.DeviceDomainId != null)
.Select(d => d.DeviceDomainId)
.ToList()
.Where(ActiveDirectory.IsValidDomainAccountId)
.Select(id => id + "$");
}
private void ProcessRepositoryEvent(RepositoryMonitorEvent Event)
{
var device = (Device)Event.Entity;
string previousDeviceDomainId = Event.GetPreviousPropertyValue<string>("DeviceDomainId");
Event.ExecuteAfterCommit(e =>
{
switch (e.EventType)
{
case RepositoryMonitorEventType.Added:
AddMember(device.DeviceDomainId + "$");
break;
case RepositoryMonitorEventType.Modified:
if (device.DeviceProfileId == DeviceProfileId)
{
if (ActiveDirectory.IsValidDomainAccountId(device.DeviceDomainId))
AddMember(device.DeviceDomainId + "$");
if (e.ModifiedProperties.Contains("DeviceDomainId"))
{
if (ActiveDirectory.IsValidDomainAccountId(previousDeviceDomainId))
RemoveMember(previousDeviceDomainId + "$");
}
}
else
{
if (e.ModifiedProperties.Contains("DeviceDomainId"))
{
if (ActiveDirectory.IsValidDomainAccountId(previousDeviceDomainId))
RemoveMember(previousDeviceDomainId + "$");
}
else
{
if (ActiveDirectory.IsValidDomainAccountId(device.DeviceDomainId))
RemoveMember(device.DeviceDomainId + "$");
}
}
break;
case RepositoryMonitorEventType.Deleted:
if (ActiveDirectory.IsValidDomainAccountId(previousDeviceDomainId))
RemoveMember(previousDeviceDomainId + "$");
break;
}
});
}
public override void Dispose()
{
if (repositorySubscription != null)
repositorySubscription.Dispose();
}
}
}