Feature #49: Active Directory Managed Groups
Document Template Attachments, Device Batches, Device Profiles and User Flags can be associated with an Active Directory group. This AD group is then automatically synchronized with relevant User/Machine accounts. Contains various other UI tweaks and configuration enhancements.
This commit is contained in:
@@ -501,9 +501,12 @@ namespace Disco.BI.DeviceBI
|
||||
}
|
||||
else
|
||||
{
|
||||
var computerId = Disco.Services.UserExtensions.SplitUserId(RepoDevice.DeviceDomainId);
|
||||
response.DeviceDomainName = computerId.Item1;
|
||||
response.DeviceComputerName = computerId.Item2;
|
||||
string accountUsername;
|
||||
ADDomain accountDomain;
|
||||
ActiveDirectory.ParseDomainAccountId(RepoDevice.DeviceDomainId, out accountUsername, out accountDomain);
|
||||
|
||||
response.DeviceDomainName = accountDomain == null ? null : accountDomain.NetBiosName;
|
||||
response.DeviceComputerName = accountUsername;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -527,16 +530,17 @@ namespace Disco.BI.DeviceBI
|
||||
domain = ActiveDirectory.Context.GetDomainFromDistinguishedName(RepoDevice.DeviceProfile.OrganisationalUnit);
|
||||
|
||||
var calculatedComputerName = RepoDevice.ComputerNameRender(Database, domain);
|
||||
var computerNameSplit = Disco.Services.UserExtensions.SplitUserId(calculatedComputerName);
|
||||
string calculatedAccountUsername;
|
||||
ActiveDirectory.ParseDomainAccountId(calculatedComputerName, out calculatedAccountUsername);
|
||||
|
||||
if (!Request.DeviceComputerName.Equals(computerNameSplit.Item2, StringComparison.OrdinalIgnoreCase))
|
||||
if (!Request.DeviceComputerName.Equals(calculatedAccountUsername, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
EnrolmentLog.LogSessionProgress(sessionId, 50, string.Format("Renaming Device: {0} -> {1}", Request.DeviceComputerName, calculatedComputerName));
|
||||
EnrolmentLog.LogSessionTaskRenamingDevice(sessionId, Request.DeviceComputerName, calculatedComputerName);
|
||||
|
||||
RepoDevice.DeviceDomainId = calculatedComputerName;
|
||||
response.DeviceDomainName = computerNameSplit.Item1;
|
||||
response.DeviceComputerName = computerNameSplit.Item2;
|
||||
response.DeviceDomainName = domain.NetBiosName;
|
||||
response.DeviceComputerName = calculatedAccountUsername;
|
||||
|
||||
// Create New Account
|
||||
string offlineProvisionDiagnosicInfo;
|
||||
|
||||
@@ -66,14 +66,10 @@ namespace Disco.BI.DocumentTemplateBI
|
||||
}
|
||||
public DocumentUniqueIdentifier(string TemplateTypeId, string DataId, string CreatorId, DateTime TimeStamp, int? Page = null, string Tag = null)
|
||||
{
|
||||
var creatorId = (string.IsNullOrEmpty(CreatorId) || CreatorId.IndexOf('\\') > -1)
|
||||
? CreatorId
|
||||
: string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, CreatorId);
|
||||
|
||||
this.Tag = Tag;
|
||||
this.TemplateTypeId = TemplateTypeId;
|
||||
this.DataId = DataId;
|
||||
this.CreatorId = creatorId;
|
||||
this.CreatorId = ActiveDirectory.ParseDomainAccountId(CreatorId);
|
||||
this.TimeStamp = TimeStamp;
|
||||
this.Page = Page ?? 0;
|
||||
}
|
||||
@@ -98,11 +94,7 @@ namespace Disco.BI.DocumentTemplateBI
|
||||
}
|
||||
if (s.Length >= 5)
|
||||
{
|
||||
var creatorId = s[4];
|
||||
if (!string.IsNullOrWhiteSpace(creatorId) && creatorId.IndexOf('\\') < 0)
|
||||
creatorId = string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, creatorId);
|
||||
|
||||
this.CreatorId = creatorId;
|
||||
this.CreatorId = ActiveDirectory.ParseDomainAccountId(s[4]);
|
||||
}
|
||||
if (s.Length >= 6)
|
||||
{
|
||||
@@ -189,13 +181,7 @@ namespace Disco.BI.DocumentTemplateBI
|
||||
}
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
|
||||
// Patch for existing documents (before DBv13 - Multi-Domain Support)
|
||||
// Add default domain to User Ids
|
||||
if (this.DataId.IndexOf('\\') < 0)
|
||||
this.DataId = string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, this.DataId);
|
||||
|
||||
User u = Database.Users.Find(this.DataId);
|
||||
User u = Database.Users.Find(ActiveDirectory.ParseDomainAccountId(this.DataId));
|
||||
if (u != null)
|
||||
{
|
||||
this._data = u;
|
||||
|
||||
@@ -0,0 +1,441 @@
|
||||
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.BI.DocumentTemplateBI.ManagedGroups
|
||||
{
|
||||
public class DocumentTemplateDevicesManagedGroup : ADManagedGroup
|
||||
{
|
||||
private const string KeyFormat = "DocumentTemplate_{0}_Devices";
|
||||
private const string DeviceDescriptionFormat = "Devices with a {0} attachment will be added to this Active Directory group.";
|
||||
private const string DescriptionFormat = "{0}s with a {1} attachment will have any associated devices added to this Active Directory group.";
|
||||
private const string CategoryDescriptionFormat = "Related Devices Linked Group";
|
||||
private const string GroupDescriptionFormat = "{0} [Document Template Devices]";
|
||||
|
||||
private IDisposable repositorySubscription;
|
||||
private IDisposable deviceRenameRepositorySubscription;
|
||||
private IDisposable jobCloseRepositorySubscription;
|
||||
private IDisposable deviceAssignmentRepositorySubscription;
|
||||
private string DocumentTemplateId;
|
||||
private string DocumentTemplateDescription;
|
||||
private string DocumentTemplateScope;
|
||||
|
||||
public override string Description { get { return GetDescription(DocumentTemplateScope, DocumentTemplateDescription); } }
|
||||
public override string CategoryDescription { get { return CategoryDescriptionFormat; } }
|
||||
public override string GroupDescription { get { return string.Format(GroupDescriptionFormat, DocumentTemplateDescription); } }
|
||||
public override bool IncludeFilterBeginDate { get { return true; } }
|
||||
|
||||
private DocumentTemplateDevicesManagedGroup(string Key, ADManagedGroupConfiguration Configuration, DocumentTemplate DocumentTemplate)
|
||||
: base(Key, Configuration)
|
||||
{
|
||||
this.DocumentTemplateId = DocumentTemplate.Id;
|
||||
this.DocumentTemplateDescription = DocumentTemplate.Description;
|
||||
this.DocumentTemplateScope = DocumentTemplate.Scope;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
// Subscribe to changes
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
// Observe Device Attachments
|
||||
repositorySubscription = DocumentTemplateManagedGroups.DeviceScopeRepositoryEvents.Value
|
||||
.Where(e => ((DeviceAttachment)e.Entity).DocumentTemplateId == DocumentTemplateId)
|
||||
.Subscribe(ProcessDeviceRepositoryEvent);
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
// Observe Job Attachments
|
||||
repositorySubscription = DocumentTemplateManagedGroups.UserScopeRepositoryEvents.Value
|
||||
.Where(e => ((JobAttachment)e.Entity).DocumentTemplateId == DocumentTemplateId)
|
||||
.Subscribe(ProcessJobRepositoryEvent);
|
||||
// Observe Job Close/Reopen
|
||||
jobCloseRepositorySubscription = DocumentTemplateManagedGroups.JobCloseRepositoryEvents.Value
|
||||
.Subscribe(ProcessJobCloseRepositoryEvent);
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
// Observe User Attachments
|
||||
repositorySubscription = DocumentTemplateManagedGroups.UserScopeRepositoryEvents.Value
|
||||
.Where(e => ((UserAttachment)e.Entity).DocumentTemplateId == DocumentTemplateId)
|
||||
.Subscribe(ProcessUserRepositoryEvent);
|
||||
// Observe Device Assignments
|
||||
deviceAssignmentRepositorySubscription = DocumentTemplateManagedGroups.DeviceAssignmentRepositoryEvents.Value
|
||||
.Subscribe(ProcessDeviceAssignmentRepositoryEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
// Observe Device Renaming (DeviceDomainId)
|
||||
deviceRenameRepositorySubscription = DocumentTemplateManagedGroups.DeviceRenameRepositoryEvents.Value
|
||||
.Subscribe(ProcessDeviceRenameRepositoryEvent);
|
||||
}
|
||||
|
||||
public static string GetKey(DocumentTemplate DocumentTemplate)
|
||||
{
|
||||
return string.Format(KeyFormat, DocumentTemplate.Id);
|
||||
}
|
||||
private static string GetDescription(string DocumentTemplateScope, string DocumentTemplateDescription)
|
||||
{
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
return string.Format(DeviceDescriptionFormat, DocumentTemplateDescription);
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
return string.Format(DescriptionFormat, DocumentTemplateScope, DocumentTemplateDescription);
|
||||
default:
|
||||
throw new ArgumentException("Unknown Document Template Scope", "Scope");
|
||||
}
|
||||
}
|
||||
public static string GetDescription(DocumentTemplate DocumentTemplate)
|
||||
{
|
||||
return GetDescription(DocumentTemplate.Scope, DocumentTemplate.Description);
|
||||
}
|
||||
public static string GetCategoryDescription(DocumentTemplate DocumentTemplate)
|
||||
{
|
||||
return CategoryDescriptionFormat;
|
||||
}
|
||||
|
||||
public static bool TryGetManagedGroup(DocumentTemplate DocumentTemplate, out DocumentTemplateDevicesManagedGroup ManagedGroup)
|
||||
{
|
||||
ADManagedGroup managedGroup;
|
||||
string key = GetKey(DocumentTemplate);
|
||||
|
||||
if (ActiveDirectory.Context.ManagedGroups.TryGetValue(key, out managedGroup))
|
||||
{
|
||||
ManagedGroup = (DocumentTemplateDevicesManagedGroup)managedGroup;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ManagedGroup = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static DocumentTemplateDevicesManagedGroup Initialize(DocumentTemplate Template)
|
||||
{
|
||||
var key = GetKey(Template);
|
||||
|
||||
if (!string.IsNullOrEmpty(Template.DevicesLinkedGroup))
|
||||
{
|
||||
var config = ADManagedGroup.ConfigurationFromJson(Template.DevicesLinkedGroup);
|
||||
|
||||
if (config != null && !string.IsNullOrWhiteSpace(config.GroupId))
|
||||
{
|
||||
var group = new DocumentTemplateDevicesManagedGroup(
|
||||
key,
|
||||
config,
|
||||
Template);
|
||||
|
||||
// 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)
|
||||
{
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
return Database.Devices
|
||||
.Where(d => d.DeviceDomainId != null && d.DeviceAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Select(d => d.DeviceDomainId)
|
||||
.ToList()
|
||||
.Where(ActiveDirectory.IsValidDomainAccountId)
|
||||
.Select(id => id + "$");
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
return Database.Jobs
|
||||
.Where(j => !j.ClosedDate.HasValue && j.Device.DeviceDomainId != null && j.JobAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Select(j => j.Device.DeviceDomainId)
|
||||
.Distinct()
|
||||
.ToList()
|
||||
.Where(ActiveDirectory.IsValidDomainAccountId)
|
||||
.Select(id => id + "$");
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
return Database.Users
|
||||
.Where(u => u.UserAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.SelectMany(u => u.DeviceUserAssignments.Where(dua => !dua.UnassignedDate.HasValue && dua.Device.DeviceDomainId != null), (u, dua) => dua.Device.DeviceDomainId)
|
||||
.ToList()
|
||||
.Where(ActiveDirectory.IsValidDomainAccountId)
|
||||
.Select(id => id + "$");
|
||||
default:
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
#region Device Scope
|
||||
private bool DeviceContainsAttachment(DiscoDataContext Database, string DeviceSerialNumber, out string DeviceAccountId)
|
||||
{
|
||||
var result = Database.Devices
|
||||
.Where(d => d.SerialNumber == DeviceSerialNumber && d.DeviceDomainId != null)
|
||||
.Select(d => new Tuple<string, bool>(d.DeviceDomainId, d.DeviceAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId)))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
DeviceAccountId = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ActiveDirectory.IsValidDomainAccountId(result.Item1))
|
||||
{
|
||||
DeviceAccountId = result.Item1 + "$";
|
||||
return result.Item2;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceAccountId = result.Item1 + "$";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessDeviceRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var attachment = (DeviceAttachment)e.Entity;
|
||||
|
||||
string deviceAccountId;
|
||||
if (DeviceContainsAttachment(e.Database, attachment.DeviceSerialNumber, out deviceAccountId))
|
||||
AddMember(attachment.DeviceSerialNumber, (database) => new string[] { deviceAccountId });
|
||||
else if (deviceAccountId != null)
|
||||
RemoveMember(attachment.DeviceSerialNumber, (database) => new string[] { deviceAccountId });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Job Scope
|
||||
private bool JobsContainAttachment(DiscoDataContext Database, int JobId, out string DeviceAccountId, out string DeviceSerialNumber)
|
||||
{
|
||||
var result = Database.Jobs
|
||||
.Where(j => j.Id == JobId && j.Device.DeviceDomainId != null)
|
||||
.Select(j => new Tuple<string, string, bool>(
|
||||
j.Device.DeviceDomainId,
|
||||
j.Device.SerialNumber,
|
||||
j.Device.Jobs.Where(dj => !dj.ClosedDate.HasValue).Any(dj => dj.JobAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId)))
|
||||
).FirstOrDefault();
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
DeviceAccountId = null;
|
||||
DeviceSerialNumber = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ActiveDirectory.IsValidDomainAccountId(result.Item1))
|
||||
{
|
||||
DeviceAccountId = result.Item1 + "$";
|
||||
DeviceSerialNumber = result.Item2;
|
||||
return result.Item3;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceAccountId = result.Item1 + "$";
|
||||
DeviceSerialNumber = result.Item2;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessJobRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var attachment = (JobAttachment)e.Entity;
|
||||
|
||||
string deviceAccountId;
|
||||
string deviceSerialNumber;
|
||||
if (JobsContainAttachment(e.Database, attachment.JobId, out deviceAccountId, out deviceSerialNumber))
|
||||
AddMember(deviceSerialNumber, (database) => new string[] { deviceAccountId });
|
||||
else if (deviceSerialNumber != null && deviceAccountId != null)
|
||||
RemoveMember(deviceSerialNumber, (database) => new string[] { deviceAccountId });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region User Scope
|
||||
private bool DeviceUserContainAttachment(DiscoDataContext Database, string UserId, out List<Tuple<string, string>> Devices)
|
||||
{
|
||||
var result = Database.Users
|
||||
.Where(u => u.UserId == UserId)
|
||||
.Select(u => new Tuple<bool, IEnumerable<Tuple<string, string>>>(
|
||||
u.UserAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId),
|
||||
u.DeviceUserAssignments
|
||||
.Where(dua => !dua.UnassignedDate.HasValue && dua.Device.DeviceDomainId != null)
|
||||
.Select(dua => new Tuple<string, string>(dua.Device.DeviceDomainId, dua.Device.SerialNumber)))
|
||||
).FirstOrDefault();
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
Devices = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Devices = result.Item2
|
||||
.Where(d => ActiveDirectory.IsValidDomainAccountId(d.Item1))
|
||||
.Select(d => Tuple.Create(d.Item1 + "$", d.Item2))
|
||||
.ToList();
|
||||
return result.Item1;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessUserRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var attachment = (UserAttachment)e.Entity;
|
||||
|
||||
List<Tuple<string, string>> devices;
|
||||
if (DeviceUserContainAttachment(e.Database, attachment.UserId, out devices))
|
||||
{
|
||||
if (devices != null)
|
||||
devices.ForEach(d => AddMember(d.Item2, (database) => new string[] { d.Item1 }));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (devices != null)
|
||||
devices.ForEach(d => RemoveMember(d.Item2, (database) => new string[] { d.Item1 }));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void ProcessDeviceRenameRepositoryEvent(RepositoryMonitorEvent Event)
|
||||
{
|
||||
var device = (Device)Event.Entity;
|
||||
var deviceSerialNumber = device.SerialNumber;
|
||||
var deviceAccountId = device.DeviceDomainId;
|
||||
var deviceAccountIdValid = ActiveDirectory.IsValidDomainAccountId(deviceAccountId);
|
||||
var devicePreviousAccountId = Event.GetPreviousPropertyValue<string>("DeviceDomainId");
|
||||
var devicePreviousAccountIdValid = ActiveDirectory.IsValidDomainAccountId(devicePreviousAccountId);
|
||||
|
||||
if (deviceAccountIdValid || devicePreviousAccountIdValid)
|
||||
{
|
||||
Event.ExecuteAfterCommit(e =>
|
||||
{
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
if (DeviceContainsAttachment(e.Database, device.SerialNumber, out deviceAccountId))
|
||||
{
|
||||
if (deviceAccountIdValid)
|
||||
AddMember(device.SerialNumber, (database) => new string[] { deviceAccountId });
|
||||
if (devicePreviousAccountIdValid)
|
||||
RemoveMember(device.SerialNumber, (database) => new string[] { devicePreviousAccountId + "$" });
|
||||
}
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
var jobsHaveTemplate = e.Database.Jobs
|
||||
.Where(j => !j.ClosedDate.HasValue && j.DeviceSerialNumber == deviceSerialNumber)
|
||||
.Any(j => j.JobAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId));
|
||||
|
||||
if (jobsHaveTemplate)
|
||||
{
|
||||
if (deviceAccountIdValid)
|
||||
AddMember(device.SerialNumber, (database) => new string[] { deviceAccountId + "$" });
|
||||
if (devicePreviousAccountIdValid)
|
||||
RemoveMember(device.SerialNumber, (database) => new string[] { devicePreviousAccountId + "$" });
|
||||
}
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
var userHasTemplate = e.Database.Devices
|
||||
.Where(d => d.SerialNumber == deviceSerialNumber)
|
||||
.Select(d => d.AssignedUser)
|
||||
.Any(u => u.UserAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId));
|
||||
|
||||
if (userHasTemplate)
|
||||
{
|
||||
if (deviceAccountIdValid)
|
||||
AddMember(device.SerialNumber, (database) => new string[] { deviceAccountId + "$" });
|
||||
if (devicePreviousAccountIdValid)
|
||||
RemoveMember(device.SerialNumber, (database) => new string[] { devicePreviousAccountId + "$" });
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessJobCloseRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var job = (Job)e.Entity;
|
||||
|
||||
if (job.DeviceSerialNumber != null)
|
||||
{
|
||||
var jobId = job.Id;
|
||||
|
||||
var relevantJob = e.Database.Jobs
|
||||
.Where(j => j.Id == jobId && j.JobAttachments.Any(ja => ja.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Any();
|
||||
|
||||
if (relevantJob)
|
||||
{
|
||||
string deviceAccountId;
|
||||
string deviceSerialNumber;
|
||||
if (JobsContainAttachment(e.Database, jobId, out deviceAccountId, out deviceSerialNumber))
|
||||
AddMember(deviceSerialNumber, (database) => new string[] { deviceAccountId });
|
||||
else
|
||||
RemoveMember(deviceSerialNumber, (database) => new string[] { deviceAccountId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessDeviceAssignmentRepositoryEvent(RepositoryMonitorEvent Event)
|
||||
{
|
||||
var device = (Device)Event.Entity;
|
||||
var deviceSerialNumber = device.SerialNumber;
|
||||
var deviceAccountId = device.DeviceDomainId;
|
||||
|
||||
if (ActiveDirectory.IsValidDomainAccountId(deviceAccountId))
|
||||
{
|
||||
var deviceCurrentAssignedUserId = device.AssignedUserId;
|
||||
var devicePreviousAssignedUserId = Event.GetPreviousPropertyValue<string>("AssignedUserId");
|
||||
|
||||
Event.ExecuteAfterCommit(e =>
|
||||
{
|
||||
bool previousUserHasTemplate = false;
|
||||
bool currentUserHasTemplate = false;
|
||||
|
||||
if (devicePreviousAssignedUserId != null)
|
||||
previousUserHasTemplate = e.Database.Users
|
||||
.Where(u => u.UserId == devicePreviousAssignedUserId && u.UserAttachments.Any(ua => ua.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Any();
|
||||
|
||||
if (deviceCurrentAssignedUserId != null)
|
||||
currentUserHasTemplate = e.Database.Users
|
||||
.Where(u => u.UserId == deviceCurrentAssignedUserId && u.UserAttachments.Any(ua => ua.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Any();
|
||||
|
||||
if (!previousUserHasTemplate && currentUserHasTemplate)
|
||||
AddMember(deviceSerialNumber, (database) => new string[] { deviceAccountId + "$" });
|
||||
else if (previousUserHasTemplate && !currentUserHasTemplate)
|
||||
RemoveMember(deviceSerialNumber, (database) => new string[] { deviceAccountId + "$" });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (repositorySubscription != null)
|
||||
repositorySubscription.Dispose();
|
||||
|
||||
if (deviceRenameRepositorySubscription != null)
|
||||
deviceRenameRepositorySubscription.Dispose();
|
||||
|
||||
if (jobCloseRepositorySubscription != null)
|
||||
jobCloseRepositorySubscription.Dispose();
|
||||
|
||||
if (deviceAssignmentRepositorySubscription != null)
|
||||
deviceAssignmentRepositorySubscription.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using Disco.Data.Repository;
|
||||
using Disco.Data.Repository.Monitor;
|
||||
using Disco.Models.Repository;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
namespace Disco.BI.DocumentTemplateBI.ManagedGroups
|
||||
{
|
||||
public static class DocumentTemplateManagedGroups
|
||||
{
|
||||
internal static Lazy<IObservable<RepositoryMonitorEvent>> DeviceScopeRepositoryEvents;
|
||||
internal static Lazy<IObservable<RepositoryMonitorEvent>> JobScopeRepositoryEvents;
|
||||
internal static Lazy<IObservable<RepositoryMonitorEvent>> UserScopeRepositoryEvents;
|
||||
|
||||
internal static Lazy<IObservable<RepositoryMonitorEvent>> DeviceRenameRepositoryEvents;
|
||||
internal static Lazy<IObservable<RepositoryMonitorEvent>> JobCloseRepositoryEvents;
|
||||
internal static Lazy<IObservable<RepositoryMonitorEvent>> DeviceAssignmentRepositoryEvents;
|
||||
|
||||
static DocumentTemplateManagedGroups()
|
||||
{
|
||||
DeviceScopeRepositoryEvents =
|
||||
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
|
||||
RepositoryMonitor.StreamAfterCommit.Where(e =>
|
||||
e.EntityType == typeof(DeviceAttachment) &&
|
||||
((DeviceAttachment)e.Entity).DocumentTemplateId != null && (
|
||||
(e.EventType == RepositoryMonitorEventType.Added) ||
|
||||
(e.EventType == RepositoryMonitorEventType.Deleted)
|
||||
)
|
||||
));
|
||||
JobScopeRepositoryEvents =
|
||||
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
|
||||
RepositoryMonitor.StreamAfterCommit.Where(e =>
|
||||
e.EntityType == typeof(JobAttachment) && (
|
||||
(e.EventType == RepositoryMonitorEventType.Added) ||
|
||||
(e.EventType == RepositoryMonitorEventType.Deleted)
|
||||
)
|
||||
));
|
||||
UserScopeRepositoryEvents =
|
||||
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
|
||||
RepositoryMonitor.StreamAfterCommit.Where(e =>
|
||||
e.EntityType == typeof(UserAttachment) && (
|
||||
(e.EventType == RepositoryMonitorEventType.Added) ||
|
||||
(e.EventType == RepositoryMonitorEventType.Deleted)
|
||||
)
|
||||
));
|
||||
|
||||
DeviceRenameRepositoryEvents =
|
||||
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
|
||||
RepositoryMonitor.StreamBeforeCommit.Where(e =>
|
||||
e.EntityType == typeof(Device) &&
|
||||
e.EventType == RepositoryMonitorEventType.Modified &&
|
||||
e.ModifiedProperties.Contains("DeviceDomainId")
|
||||
));
|
||||
JobCloseRepositoryEvents =
|
||||
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
|
||||
RepositoryMonitor.StreamAfterCommit.Where(e =>
|
||||
e.EntityType == typeof(Job) &&
|
||||
(((Job)e.Entity).DeviceSerialNumber != null || ((Job)e.Entity).UserId != null) &&
|
||||
e.EventType == RepositoryMonitorEventType.Modified &&
|
||||
e.ModifiedProperties.Contains("ClosedDate")
|
||||
));
|
||||
DeviceAssignmentRepositoryEvents =
|
||||
new Lazy<IObservable<RepositoryMonitorEvent>>(() =>
|
||||
RepositoryMonitor.StreamBeforeCommit.Where(e =>
|
||||
e.EntityType == typeof(Device) &&
|
||||
e.EventType == RepositoryMonitorEventType.Modified &&
|
||||
e.ModifiedProperties.Contains("AssignedUserId")
|
||||
));
|
||||
}
|
||||
|
||||
public static void Initialize(DiscoDataContext Database)
|
||||
{
|
||||
Database.DocumentTemplates
|
||||
.Where(dp => dp.DevicesLinkedGroup != null || dp.UsersLinkedGroup != null)
|
||||
.ToList()
|
||||
.ForEach(dp =>
|
||||
{
|
||||
DocumentTemplateDevicesManagedGroup.Initialize(dp);
|
||||
DocumentTemplateUsersManagedGroup.Initialize(dp);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
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.BI.DocumentTemplateBI.ManagedGroups
|
||||
{
|
||||
public class DocumentTemplateUsersManagedGroup : ADManagedGroup
|
||||
{
|
||||
private const string KeyFormat = "DocumentTemplate_{0}_Users";
|
||||
private const string UserDescriptionFormat = "Users with a {0} attachment will be added to this Active Directory group.";
|
||||
private const string DescriptionFormat = "{0}s with a {1} attachment will have any associated users added to this Active Directory group.";
|
||||
private const string CategoryDescriptionFormat = "Related Users Linked Group";
|
||||
private const string GroupDescriptionFormat = "{0} [Document Template Users]";
|
||||
|
||||
private IDisposable repositorySubscription;
|
||||
private IDisposable jobCloseRepositorySubscription;
|
||||
private IDisposable deviceAssignmentRepositorySubscription;
|
||||
private string DocumentTemplateId;
|
||||
private string DocumentTemplateDescription;
|
||||
private string DocumentTemplateScope;
|
||||
|
||||
public override string Description { get { return GetDescription(DocumentTemplateScope, DocumentTemplateDescription); } }
|
||||
public override string CategoryDescription { get { return CategoryDescriptionFormat; } }
|
||||
public override string GroupDescription { get { return string.Format(GroupDescriptionFormat, DocumentTemplateDescription); } }
|
||||
public override bool IncludeFilterBeginDate { get { return true; } }
|
||||
|
||||
private DocumentTemplateUsersManagedGroup(string Key, ADManagedGroupConfiguration Configuration, DocumentTemplate DocumentTemplate)
|
||||
: base(Key, Configuration)
|
||||
{
|
||||
this.DocumentTemplateId = DocumentTemplate.Id;
|
||||
this.DocumentTemplateDescription = DocumentTemplate.Description;
|
||||
this.DocumentTemplateScope = DocumentTemplate.Scope;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
// Subscribe to changes
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
// Observe Device Attachments
|
||||
repositorySubscription = DocumentTemplateManagedGroups.DeviceScopeRepositoryEvents.Value
|
||||
.Where(e => ((DeviceAttachment)e.Entity).DocumentTemplateId == DocumentTemplateId)
|
||||
.Subscribe(ProcessDeviceRepositoryEvent);
|
||||
// Observe Device Assignments
|
||||
deviceAssignmentRepositorySubscription = DocumentTemplateManagedGroups.DeviceAssignmentRepositoryEvents.Value
|
||||
.Subscribe(ProcessDeviceAssignmentRepositoryEvent);
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
// Observe Job Attachments
|
||||
repositorySubscription = DocumentTemplateManagedGroups.UserScopeRepositoryEvents.Value
|
||||
.Where(e => ((JobAttachment)e.Entity).DocumentTemplateId == DocumentTemplateId)
|
||||
.Subscribe(ProcessJobRepositoryEvent);
|
||||
// Observe Job Close/Reopen
|
||||
jobCloseRepositorySubscription = DocumentTemplateManagedGroups.JobCloseRepositoryEvents.Value
|
||||
.Subscribe(ProcessJobCloseRepositoryEvent);
|
||||
break;
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
// Observe User Attachments
|
||||
repositorySubscription = DocumentTemplateManagedGroups.UserScopeRepositoryEvents.Value
|
||||
.Where(e => ((UserAttachment)e.Entity).DocumentTemplateId == DocumentTemplateId)
|
||||
.Subscribe(ProcessUserRepositoryEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetKey(DocumentTemplate DocumentTemplate)
|
||||
{
|
||||
return string.Format(KeyFormat, DocumentTemplate.Id);
|
||||
}
|
||||
private static string GetDescription(string DocumentTemplateScope, string DocumentTemplateDescription)
|
||||
{
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
return string.Format(DescriptionFormat, DocumentTemplateScope, DocumentTemplateDescription);
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
return string.Format(UserDescriptionFormat, DocumentTemplateDescription);
|
||||
default:
|
||||
throw new ArgumentException("Unknown Document Template Scope", "Scope");
|
||||
}
|
||||
}
|
||||
public static string GetDescription(DocumentTemplate DocumentTemplate)
|
||||
{
|
||||
return GetDescription(DocumentTemplate.Scope, DocumentTemplate.Description);
|
||||
}
|
||||
public static string GetCategoryDescription(DocumentTemplate DocumentTemplate)
|
||||
{
|
||||
return CategoryDescriptionFormat;
|
||||
}
|
||||
|
||||
public static bool TryGetManagedGroup(DocumentTemplate DocumentTemplate, out DocumentTemplateUsersManagedGroup ManagedGroup)
|
||||
{
|
||||
ADManagedGroup managedGroup;
|
||||
string key = GetKey(DocumentTemplate);
|
||||
|
||||
if (ActiveDirectory.Context.ManagedGroups.TryGetValue(key, out managedGroup))
|
||||
{
|
||||
ManagedGroup = (DocumentTemplateUsersManagedGroup)managedGroup;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ManagedGroup = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static DocumentTemplateUsersManagedGroup Initialize(DocumentTemplate Template)
|
||||
{
|
||||
var key = GetKey(Template);
|
||||
|
||||
if (!string.IsNullOrEmpty(Template.UsersLinkedGroup))
|
||||
{
|
||||
var config = ADManagedGroup.ConfigurationFromJson(Template.UsersLinkedGroup);
|
||||
|
||||
if (config != null && !string.IsNullOrWhiteSpace(config.GroupId))
|
||||
{
|
||||
var group = new DocumentTemplateUsersManagedGroup(
|
||||
key,
|
||||
config,
|
||||
Template);
|
||||
|
||||
// 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)
|
||||
{
|
||||
switch (DocumentTemplateScope)
|
||||
{
|
||||
case DocumentTemplate.DocumentTemplateScopes.Device:
|
||||
return Database.Devices
|
||||
.Where(d => d.AssignedUserId != null && d.DeviceAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Select(d => d.AssignedUserId);
|
||||
case DocumentTemplate.DocumentTemplateScopes.Job:
|
||||
return Database.Jobs
|
||||
.Where(j => !j.ClosedDate.HasValue && j.UserId != null && j.JobAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Select(j => j.UserId)
|
||||
.Distinct();
|
||||
case DocumentTemplate.DocumentTemplateScopes.User:
|
||||
return Database.Users
|
||||
.Where(u => u.UserAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Select(u => u.UserId);
|
||||
default:
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
#region Device Scope
|
||||
private bool DeviceContainsAttachment(DiscoDataContext Database, string DeviceSerialNumber, out string UserId)
|
||||
{
|
||||
var result = Database.Devices
|
||||
.Where(d => d.SerialNumber == DeviceSerialNumber && d.AssignedUser != null)
|
||||
.Select(d => new Tuple<string, bool>(d.AssignedUserId, d.DeviceAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId)))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
UserId = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserId = result.Item1;
|
||||
return result.Item2;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessDeviceRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var attachment = (DeviceAttachment)e.Entity;
|
||||
|
||||
string userId;
|
||||
if (DeviceContainsAttachment(e.Database, attachment.DeviceSerialNumber, out userId))
|
||||
AddMember(userId, (database) => new string[] { userId });
|
||||
else if (userId != null)
|
||||
RemoveMember(userId, (database) => new string[] { userId });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Job Scope
|
||||
private bool JobsContainAttachment(DiscoDataContext Database, int JobId, out string UserId)
|
||||
{
|
||||
var result = Database.Jobs
|
||||
.Where(j => j.Id == JobId && j.UserId != null)
|
||||
.Select(j => new Tuple<string, bool>(
|
||||
j.UserId,
|
||||
j.User.Jobs.Where(uj => !uj.ClosedDate.HasValue).Any(uj => uj.JobAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId)))
|
||||
).FirstOrDefault();
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
UserId = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserId = result.Item1;
|
||||
return result.Item2;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessJobRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var attachment = (JobAttachment)e.Entity;
|
||||
|
||||
string userId;
|
||||
if (JobsContainAttachment(e.Database, attachment.JobId, out userId))
|
||||
AddMember(userId, (database) => new string[] { userId });
|
||||
else if (userId != null)
|
||||
RemoveMember(userId, (database) => new string[] { userId });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region User Scope
|
||||
private bool UserContainAttachment(DiscoDataContext Database, string UserId)
|
||||
{
|
||||
var result = Database.Users
|
||||
.Where(u => u.UserId == UserId)
|
||||
.Any(u => u.UserAttachments.Any(a => a.DocumentTemplateId == this.DocumentTemplateId));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ProcessUserRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var attachment = (UserAttachment)e.Entity;
|
||||
var userId = attachment.UserId;
|
||||
|
||||
if (UserContainAttachment(e.Database, userId))
|
||||
AddMember(userId, (database) => new string[] { userId });
|
||||
else
|
||||
RemoveMember(userId, (database) => new string[] { userId });
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void ProcessJobCloseRepositoryEvent(RepositoryMonitorEvent e)
|
||||
{
|
||||
var job = (Job)e.Entity;
|
||||
|
||||
if (job.UserId != null)
|
||||
{
|
||||
var jobId = job.Id;
|
||||
|
||||
var relevantJob = e.Database.Jobs
|
||||
.Where(j => j.Id == jobId && j.JobAttachments.Any(ja => ja.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Any();
|
||||
|
||||
if (relevantJob)
|
||||
{
|
||||
string userId;
|
||||
if (JobsContainAttachment(e.Database, jobId, out userId))
|
||||
AddMember(userId, (database) => new string[] { userId });
|
||||
else
|
||||
RemoveMember(userId, (database) => new string[] { userId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessDeviceAssignmentRepositoryEvent(RepositoryMonitorEvent Event)
|
||||
{
|
||||
var device = (Device)Event.Entity;
|
||||
var deviceSerialNumber = device.SerialNumber;
|
||||
|
||||
var relevantDevice = Event.Database.Devices
|
||||
.Where(d => d.SerialNumber == deviceSerialNumber && d.DeviceAttachments.Any(ja => ja.DocumentTemplateId == this.DocumentTemplateId))
|
||||
.Any();
|
||||
|
||||
if (relevantDevice)
|
||||
{
|
||||
var deviceCurrentAssignedUserId = device.AssignedUserId;
|
||||
var devicePreviousAssignedUserId = Event.GetPreviousPropertyValue<string>("AssignedUserId");
|
||||
|
||||
Event.ExecuteAfterCommit(e =>
|
||||
{
|
||||
if (devicePreviousAssignedUserId != null)
|
||||
RemoveMember(devicePreviousAssignedUserId, (database) => new string[] { devicePreviousAssignedUserId });
|
||||
|
||||
if (deviceCurrentAssignedUserId != null)
|
||||
AddMember(deviceCurrentAssignedUserId, (database) => new string[] { deviceCurrentAssignedUserId });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (repositorySubscription != null)
|
||||
repositorySubscription.Dispose();
|
||||
|
||||
if (jobCloseRepositorySubscription != null)
|
||||
jobCloseRepositorySubscription.Dispose();
|
||||
|
||||
if (deviceAssignmentRepositorySubscription != null)
|
||||
deviceAssignmentRepositorySubscription.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Disco.Services.Tasks;
|
||||
using Disco.BI.Extensions;
|
||||
using Disco.Data.Repository;
|
||||
using Disco.Services.Tasks;
|
||||
using Quartz;
|
||||
using Disco.BI.Extensions;
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.BI.Expressions
|
||||
{
|
||||
@@ -20,7 +17,7 @@ namespace Disco.BI.Expressions
|
||||
|
||||
public override void InitalizeScheduledTask(DiscoDataContext Database)
|
||||
{
|
||||
// Run in Background 1 Second after Scheduled (on App Startup)
|
||||
// Run in Background 5 Second after Scheduled (on App Startup)
|
||||
TriggerBuilder triggerBuilder = TriggerBuilder.Create().StartAt(new DateTimeOffset(DateTime.Now).AddSeconds(5));
|
||||
|
||||
this.ScheduleTask(triggerBuilder);
|
||||
@@ -37,8 +34,6 @@ namespace Disco.BI.Expressions
|
||||
documentTemplate.FilterExpressionFromCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Services.Interop.ActiveDirectory;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.BI.Expressions.Extensions
|
||||
{
|
||||
@@ -11,7 +12,7 @@ namespace Disco.BI.Expressions.Extensions
|
||||
{
|
||||
var adMachineAccount = Device.ActiveDirectoryAccount(PropertyName);
|
||||
if (adMachineAccount != null)
|
||||
return adMachineAccount.GetPropertyValue(PropertyName, Index);
|
||||
return adMachineAccount.GetPropertyValues<object>(PropertyName).Skip(Index).FirstOrDefault();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Disco.BI.Extensions;
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Services.Interop.ActiveDirectory;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.BI.Expressions.Extensions
|
||||
{
|
||||
@@ -11,7 +11,7 @@ namespace Disco.BI.Expressions.Extensions
|
||||
{
|
||||
var adUserAccount = User.ActiveDirectoryAccount(PropertyName);
|
||||
if (adUserAccount != null)
|
||||
return adUserAccount.GetPropertyValue(PropertyName, Index);
|
||||
return adUserAccount.GetPropertyValues<object>(PropertyName).Skip(Index).FirstOrDefault();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Disco.BI.Extensions
|
||||
|
||||
public static bool UpdateLastNetworkLogonDate(this Device Device)
|
||||
{
|
||||
return Disco.Services.Interop.ActiveDirectory.ADTaskUpdateNetworkLogonDates.UpdateLastNetworkLogonDate(Device);
|
||||
return Disco.Services.Interop.ActiveDirectory.ADNetworkLogonDatesUpdateTask.UpdateLastNetworkLogonDate(Device);
|
||||
}
|
||||
|
||||
public static DeviceAttachment CreateAttachment(this Device Device, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, byte[] PdfThumbnail = null)
|
||||
@@ -142,10 +142,7 @@ namespace Disco.BI.Extensions
|
||||
Database.Devices.Add(d2);
|
||||
if (!string.IsNullOrEmpty(d.AssignedUserId))
|
||||
{
|
||||
if (!d.AssignedUserId.Contains('\\'))
|
||||
d.AssignedUserId = string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, d.AssignedUserId);
|
||||
|
||||
User u = UserService.GetUser(d.AssignedUserId, Database, true);
|
||||
User u = UserService.GetUser(ActiveDirectory.ParseDomainAccountId(d.AssignedUserId), Database, true);
|
||||
d2.AssignDevice(Database, u);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,10 +66,8 @@ namespace Disco.BI.Interop.Pdf
|
||||
for (int idIndex = 0; idIndex < DataObjectsIds.Length; idIndex++)
|
||||
{
|
||||
string dataObjectId = DataObjectsIds[idIndex];
|
||||
if (!dataObjectId.Contains('\\'))
|
||||
dataObjectId = ActiveDirectory.Context.PrimaryDomain.NetBiosName + @"\" + dataObjectId;
|
||||
|
||||
DataObjects[idIndex] = UserService.GetUser(dataObjectId, Database, true);
|
||||
DataObjects[idIndex] = UserService.GetUser(ActiveDirectory.ParseDomainAccountId(dataObjectId), Database, true);
|
||||
if (DataObjects[idIndex] == null)
|
||||
throw new Exception(string.Format("Unknown Username specified: {0}", dataObjectId));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user