using AutoMapper; using DigitalData.Core.Contracts.Application; using System.DirectoryServices; using System.Diagnostics.CodeAnalysis; using System.DirectoryServices.AccountManagement; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System.Configuration; namespace DigitalData.Core.Application { [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "")] public class DirectoryService : ServiceBase, IDirectoryService { protected IMapper _mapper; protected readonly DirectorySearcher _groupSearcher; IConfiguration _configuration; public readonly string SearchRootPath; public DirectoryService(IMapper mapper, IConfiguration configuration, ILogger logger) { _mapper = mapper; _configuration = configuration; var searchRoot = configuration["DirectorySearch:SearchRootPath"]; logger.LogInformation($"Search Root is {searchRoot}."); SearchRootPath = _configuration["DirectorySearch:SearchRootPath"] ?? throw new ConfigurationErrorsException("SearchRootPath configuration is missing."); _groupSearcher = new DirectorySearcher() { Filter = "(&(objectClass=group) (samAccountName=*))", SearchScope = SearchScope.Subtree, SizeLimit = 5000, SearchRoot = new DirectoryEntry(searchRoot) }; } public IServiceResult> ReadAllGroupAsCollection() { List list = new(); foreach (SearchResult result in _groupSearcher.FindAll()) { ResultPropertyCollection rpc = result.Properties; list.Add(rpc); } return Successful>(list); } public IServiceResult> ReadAllGroupAsCollection(string serverAddress, string username, string password) { var searcher = new DirectorySearcher() { Filter = "(&(objectClass=user)(sAMAccountName=*))", SearchScope = SearchScope.Subtree, SizeLimit = 5000, SearchRoot = new DirectoryEntry($"LDAP://{serverAddress}/DC=dd-gan,DC=local,DC=digitaldata,DC=works", username, password) }; List list = new(); foreach (SearchResult result in searcher.FindAll()) { ResultPropertyCollection rpc = result.Properties; list.Add(rpc); } return Successful>(list); } public IServiceResult>> ReadGroupByPropertyName(string propertyName = "samaccountname") { List> list = new(); foreach (SearchResult result in _groupSearcher.FindAll()) { var value = result.Properties[propertyName]; if (value is not null) list.Add(new Dictionary() { [propertyName] = value }); } return Successful>>(list); } public IServiceResult> ReadUserByGroup(string groupIdentityValue, IdentityType groupIdentityType = IdentityType.Name, bool recursive = true) { List upDTOs = new(); using PrincipalContext context = new(ContextType.Domain); using GroupPrincipal? groupPrincipal = GroupPrincipal.FindByIdentity(context, groupIdentityType, groupIdentityValue); if (groupPrincipal is null) return Failed>(); using PrincipalSearchResult principalSearchResult = groupPrincipal.GetMembers(recursive); foreach (Principal principal in principalSearchResult) { if (principal is UserPrincipal userPrincipal) { var upDto = _mapper.MapOrThrow(userPrincipal); upDTOs.Add(upDto); } } return Successful>(upDTOs); } } }