diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..3729ff0
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
\ No newline at end of file
diff --git a/ActiveDirectoryToRestApi.sln b/ActiveDirectoryToRestApi.sln
new file mode 100644
index 0000000..ff0c216
--- /dev/null
+++ b/ActiveDirectoryToRestApi.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34024.191
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActiveDirectoryToRestApi", "src\ActiveDirectoryToRestApi\ActiveDirectoryToRestApi.csproj", "{2A1D2EF2-8050-48ED-AD6A-0049D800DE39}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{69C1A7CC-CE13-44EC-924A-104C576C2D34}"
+ ProjectSection(SolutionItems) = preProject
+ LICENSE = LICENSE
+ README.md = README.md
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2A1D2EF2-8050-48ED-AD6A-0049D800DE39}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D76E9DAF-9C86-445C-B53D-A96BC45CD2C9}
+ EndGlobalSection
+EndGlobal
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f8c464c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 zimbres
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..eb70287
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# ActiveDirectoryToRestApi
+
+Rest Api to get some data from Active Directory by LDAP
\ No newline at end of file
diff --git a/src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj b/src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj
new file mode 100644
index 0000000..90dfb15
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net7.0
+ disable
+ enable
+ Linux
+ ..\..
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ActiveDirectoryToRestApi/Configurations/LdapConfigs.cs b/src/ActiveDirectoryToRestApi/Configurations/LdapConfigs.cs
new file mode 100644
index 0000000..07df7c7
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Configurations/LdapConfigs.cs
@@ -0,0 +1,10 @@
+namespace ActiveDirectoryToRestApi.Configurations;
+
+public class LdapConfigs
+{
+ public string Server { get; set; }
+ public string DomainName { get; set; }
+ public string User { get; set; }
+ public string Pass { get; set; }
+ public string DistinguishedName { get; set; }
+}
diff --git a/src/ActiveDirectoryToRestApi/Controllers/GroupController.cs b/src/ActiveDirectoryToRestApi/Controllers/GroupController.cs
new file mode 100644
index 0000000..10a0b70
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Controllers/GroupController.cs
@@ -0,0 +1,26 @@
+namespace ActiveDirectoryToRestApi.Controllers;
+
+[ApiController]
+[Route("[controller]")]
+public class GroupController : ControllerBase
+{
+ private readonly ILogger _logger;
+ private readonly LdapService _ldapService;
+
+ public GroupController(ILogger logger, LdapService ldapService)
+ {
+ _logger = logger;
+ _ldapService = ldapService;
+ }
+
+ [HttpPost("/group")]
+ public ActionResult Group(string group = "mygroup")
+ {
+ var members = _ldapService.GetGroupMembers(group);
+ if (members == null)
+ {
+ return NotFound();
+ }
+ return members;
+ }
+}
diff --git a/src/ActiveDirectoryToRestApi/Controllers/UserController.cs b/src/ActiveDirectoryToRestApi/Controllers/UserController.cs
new file mode 100644
index 0000000..e450c5c
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Controllers/UserController.cs
@@ -0,0 +1,50 @@
+namespace ActiveDirectoryToRestApi.Controllers;
+
+[ApiController]
+[Route("[controller]")]
+public class UserController : ControllerBase
+{
+ private readonly ILogger _logger;
+ private readonly LdapService _ldapService;
+ private readonly AuthUserService _authUserService;
+
+ public UserController(ILogger logger, LdapService ldapService, AuthUserService authUserService)
+ {
+ _logger = logger;
+ _ldapService = ldapService;
+ _authUserService = authUserService;
+ }
+
+ [HttpPost("/email")]
+ public ActionResult Email(string email = "test.user@zimbres.com")
+ {
+ var user = _ldapService.GetUserByEmail(email);
+ if (user == null)
+ {
+ return NotFound();
+ }
+ return user;
+ }
+
+ [HttpPost("/username")]
+ public ActionResult Username(string username = "testUser")
+ {
+ var user = _ldapService.GetUserByUserName(username);
+ if (user == null)
+ {
+ return NotFound();
+ }
+ return user;
+ }
+
+ [HttpPost("/authUser")]
+ public IActionResult AuthUser(UserLogin userLogin)
+ {
+ var status = _authUserService.AuthUser(userLogin.UserName, userLogin.Password);
+ if (status)
+ {
+ return Ok();
+ }
+ return Unauthorized();
+ }
+}
diff --git a/src/ActiveDirectoryToRestApi/Dockerfile b/src/ActiveDirectoryToRestApi/Dockerfile
new file mode 100644
index 0000000..7edf0f7
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Dockerfile
@@ -0,0 +1,20 @@
+FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
+RUN apt update && apt install -y --no-install-recommends libldap-2.4-2 && rm -rf /var/lib/apt/lists/*
+WORKDIR /app
+EXPOSE 80
+
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
+WORKDIR /src
+COPY ["src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj", "src/ActiveDirectoryToRestApi/"]
+RUN dotnet restore "src/ActiveDirectoryToRestApi/ActiveDirectoryToRestApi.csproj"
+COPY . .
+WORKDIR "/src/src/ActiveDirectoryToRestApi"
+RUN dotnet build "ActiveDirectoryToRestApi.csproj" -c Release -o /app/build
+
+FROM build AS publish
+RUN dotnet publish "ActiveDirectoryToRestApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "ActiveDirectoryToRestApi.dll"]
\ No newline at end of file
diff --git a/src/ActiveDirectoryToRestApi/Extensions/LdapAttrExtensions.cs b/src/ActiveDirectoryToRestApi/Extensions/LdapAttrExtensions.cs
new file mode 100644
index 0000000..224bb3d
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Extensions/LdapAttrExtensions.cs
@@ -0,0 +1,56 @@
+namespace ActiveDirectoryToRestApi.Extensions;
+
+public static class LdapAttrExtensions
+{
+ public static string ConvertToDateTime(this string ldapTime)
+ {
+ if (ldapTime == "0" || ldapTime == "9223372036854775807") return "Never";
+ var date = long.Parse(ldapTime);
+
+ return DateTime.FromFileTime(date).ToString();
+ }
+
+ public static bool IsExpired(this string ldapTime)
+ {
+ if (ldapTime == "0" || ldapTime == "9223372036854775807") return false;
+ var expiration = DateTime.FromFileTime(long.Parse(ldapTime));
+ if (expiration < DateTime.Now) return true;
+
+ return false;
+ }
+
+ public static bool IsPasswordExpired(this string userAccountControl)
+ {
+ if (userAccountControl == "8388608") return true;
+
+ return false;
+ }
+
+ public static bool IsEnabled(this string userAccountControl)
+ {
+ if (userAccountControl == "512" || userAccountControl == "66048" || userAccountControl == "262656") return true;
+
+ return false;
+ }
+
+ public static bool IsPasswordNeverExpire(this string userAccountControl)
+ {
+ if (userAccountControl == "66048" || userAccountControl == "66050") return true;
+
+ return false;
+ }
+
+ public static string GroupType(this string groupType)
+ {
+ return groupType switch
+ {
+ "2" => "Global distribution group",
+ "4" => "Global distribution group",
+ "8" => "Universal distribution group",
+ "-2147483646" => "Global security group",
+ "-2147483644" => "Domain local security group",
+ "-2147483640" => "Universal security group",
+ _ => null,
+ };
+ }
+}
diff --git a/src/ActiveDirectoryToRestApi/GlobalUsings.cs b/src/ActiveDirectoryToRestApi/GlobalUsings.cs
new file mode 100644
index 0000000..368e045
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/GlobalUsings.cs
@@ -0,0 +1,9 @@
+global using ActiveDirectoryToRestApi.Configurations;
+global using ActiveDirectoryToRestApi.Extensions;
+global using ActiveDirectoryToRestApi.Models;
+global using ActiveDirectoryToRestApi.Services;
+global using Microsoft.AspNetCore.Mvc;
+global using System.ComponentModel;
+global using System.ComponentModel.DataAnnotations;
+global using System.DirectoryServices.Protocols;
+global using System.Net;
diff --git a/src/ActiveDirectoryToRestApi/Models/Group.cs b/src/ActiveDirectoryToRestApi/Models/Group.cs
new file mode 100644
index 0000000..81952c8
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Models/Group.cs
@@ -0,0 +1,9 @@
+namespace ActiveDirectoryToRestApi.Models;
+
+public class Group
+{
+ public string Name { get; set; }
+ public string Type { get; set; }
+ public string DistinguishedName { get; set; }
+ public List Members { get; set; } = new();
+}
diff --git a/src/ActiveDirectoryToRestApi/Models/User.cs b/src/ActiveDirectoryToRestApi/Models/User.cs
new file mode 100644
index 0000000..645f8a3
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Models/User.cs
@@ -0,0 +1,20 @@
+namespace ActiveDirectoryToRestApi.Models;
+
+public class User
+{
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string DisplayName { get; set; }
+ public string Email { get; set; }
+ public string LogonName { get; set; }
+ public string SamAccountName { get; set; }
+ public bool Enabled { get; set; }
+ public bool PasswordNeverExpire { get; set; }
+ public bool PasswordExpired { get; set; }
+ public string PasswordLastSet { get; set; }
+ public string PasswordExpiration { get; set; }
+ public bool Expired { get; set; }
+ public string Expiration { get; set; }
+ public string DistinguishedName { get; set; }
+ public List Groups { get; set; }
+}
diff --git a/src/ActiveDirectoryToRestApi/Models/UserLogin.cs b/src/ActiveDirectoryToRestApi/Models/UserLogin.cs
new file mode 100644
index 0000000..3328539
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Models/UserLogin.cs
@@ -0,0 +1,12 @@
+namespace ActiveDirectoryToRestApi.Models;
+
+public class UserLogin
+{
+ [Required]
+ [DefaultValue("testUser")]
+ public string UserName { get; set; }
+
+ [Required]
+ [DefaultValue("Thi$1sMyPassw0rd")]
+ public string Password { get; set; }
+}
diff --git a/src/ActiveDirectoryToRestApi/Program.cs b/src/ActiveDirectoryToRestApi/Program.cs
new file mode 100644
index 0000000..5b2000a
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Program.cs
@@ -0,0 +1,31 @@
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddControllers();
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen();
+builder.Services.AddSingleton(provider =>
+{
+ var configs = builder.Configuration.GetSection(nameof(LdapConfigs)).Get();
+ var endpoint = new LdapDirectoryIdentifier(configs.Server, false, false);
+ var ldapConnection = new LdapConnection(endpoint,
+ new NetworkCredential($"{configs.User}@{configs.DomainName}", configs.Pass))
+ {
+ AuthType = AuthType.Basic
+ };
+ ldapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
+ ldapConnection.Bind();
+ return ldapConnection;
+});
+builder.Services.AddSingleton();
+builder.Services.AddTransient();
+
+var app = builder.Build();
+
+app.UseSwagger();
+app.UseSwaggerUI();
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Run();
diff --git a/src/ActiveDirectoryToRestApi/Properties/launchSettings.json b/src/ActiveDirectoryToRestApi/Properties/launchSettings.json
new file mode 100644
index 0000000..c6ecdea
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Properties/launchSettings.json
@@ -0,0 +1,40 @@
+{
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5220"
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": false,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Docker": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_URLS": "http://+:80"
+ },
+ "publishAllPorts": true
+ }
+ },
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:20943",
+ "sslPort": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ActiveDirectoryToRestApi/Services/AuthUserService.cs b/src/ActiveDirectoryToRestApi/Services/AuthUserService.cs
new file mode 100644
index 0000000..74616f7
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Services/AuthUserService.cs
@@ -0,0 +1,32 @@
+namespace ActiveDirectoryToRestApi.Services;
+
+public class AuthUserService
+{
+ private readonly IConfiguration _configuration;
+
+ public AuthUserService(IConfiguration configuration)
+ {
+ _configuration = configuration;
+ }
+
+ public bool AuthUser(string username, string password)
+ {
+ var configs = _configuration.GetSection(nameof(LdapConfigs)).Get();
+ try
+ {
+ var endpoint = new LdapDirectoryIdentifier(configs.Server, false, false);
+ using var connection = new LdapConnection(endpoint,
+ new NetworkCredential($"{configs.DomainName}\\{username}", password))
+ {
+ AuthType = AuthType.Basic
+ };
+ connection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
+ connection.Bind();
+ return true;
+ }
+ catch (LdapException)
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/ActiveDirectoryToRestApi/Services/LdapService.cs b/src/ActiveDirectoryToRestApi/Services/LdapService.cs
new file mode 100644
index 0000000..beec255
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/Services/LdapService.cs
@@ -0,0 +1,177 @@
+namespace ActiveDirectoryToRestApi.Services;
+
+public class LdapService
+{
+ private readonly LdapConfigs _ldapConfigs;
+ private readonly LdapConnection _connection;
+ private readonly IConfiguration _configuration;
+
+ public LdapService(LdapConnection connection, IConfiguration configuration)
+ {
+ _connection = connection;
+ _configuration = configuration;
+ _ldapConfigs = _configuration.GetSection(nameof(LdapConfigs)).Get();
+ }
+ public User GetUserByUserName(string username)
+ {
+ string filter = $"(&(objectClass=user)(objectCategory=person)(sAMAccountName={username}))";
+ return GetUser(filter);
+ }
+
+ public User GetUserByEmail(string email)
+ {
+ string filter = $"(&(objectClass=user)(objectCategory=person)(mail={email}))";
+ return GetUser(filter);
+ }
+
+ private User GetUser(string filter)
+ {
+ string[] attributesToReturn = { "givenName", "sn", "mail", "userPrincipalName", "displayName", "sAMAccountName",
+ "userAccountControl", "accountExpires", "memberOf", "distinguishedName", "pwdLastSet" };
+
+ SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToReturn);
+
+ SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
+
+ if (searchResponse.Entries.Count > 0)
+ {
+ SearchResultEntry entry = searchResponse.Entries[0];
+
+ string userAccountControl = entry.Attributes["userAccountControl"][0].ToString();
+ string accountExpires = entry.Attributes["accountExpires"][0].ToString();
+ string expiration = accountExpires.ConvertToDateTime();
+ string pwdLastSet = entry.Attributes["pwdLastSet"][0].ToString().ConvertToDateTime();
+ string passwordExpiration = GetPasswordExpiration(pwdLastSet);
+ bool expired = accountExpires.IsExpired();
+ string mail = entry.Attributes["mail"]?[0].ToString() ?? "";
+ string givenName = entry.Attributes["givenName"]?[0].ToString() ?? "";
+ string sn = entry.Attributes["sn"]?[0].ToString() ?? "";
+ string displayName = entry.Attributes["displayName"]?[0].ToString() ?? "";
+ string sAMAccountName = entry.Attributes["sAMAccountName"][0].ToString();
+ string userPrincipalName = entry.Attributes["userPrincipalName"]?[0].ToString() ?? "";
+ string distinguishedName = entry.DistinguishedName;
+ bool enabled = userAccountControl.IsEnabled();
+ bool passwordNeverExpire = userAccountControl.IsPasswordNeverExpire();
+ bool passwordExpired = userAccountControl.IsPasswordExpired();
+
+ var groups = new List();
+ var memberOfAttribute = entry.Attributes["memberOf"];
+ if (memberOfAttribute != null)
+ {
+ foreach (var groupDn in memberOfAttribute.GetValues(typeof(string)))
+ {
+ groups.Add(ParseGroupName(groupDn.ToString()));
+ }
+ }
+
+ var user = new User
+ {
+ DisplayName = displayName,
+ Email = mail,
+ SamAccountName = sAMAccountName,
+ Enabled = enabled,
+ LogonName = userPrincipalName,
+ FirstName = givenName,
+ LastName = sn,
+ PasswordNeverExpire = passwordNeverExpire,
+ PasswordExpired = passwordExpired,
+ PasswordLastSet = pwdLastSet,
+ PasswordExpiration = passwordExpiration,
+ Expiration = expiration,
+ Expired = expired,
+ DistinguishedName = distinguishedName,
+ Groups = groups
+ };
+ return user;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private static string ParseGroupName(string groupDn)
+ {
+ int startIndex = groupDn.IndexOf('=') + 1;
+ int endIndex = groupDn.IndexOf(',');
+
+ if (startIndex > 0 && endIndex > 0)
+ {
+ return groupDn[startIndex..endIndex];
+ }
+ else
+ {
+ return groupDn;
+ }
+ }
+
+ public Group GetGroupMembers(string groupName)
+ {
+ Group group = GetGroup(groupName);
+
+ if (group is null) return null;
+
+ string filter = $"(&(objectCategory=user)(memberOf={group.DistinguishedName}))";
+ string[] attributesToReturn = { "sAMAccountName" };
+
+ SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToReturn);
+ SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
+
+ foreach (SearchResultEntry entry in searchResponse.Entries)
+ {
+ group.Members.Add(entry.Attributes["sAMAccountName"][0].ToString());
+ }
+ return group;
+ }
+
+ private Group GetGroup(string groupName)
+ {
+ string filter = $"(&(objectClass=group)(cn={groupName}))";
+ string[] attributesToReturn = { "distinguishedName", "cn", "groupType" };
+
+ SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToReturn);
+ SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
+
+ if (searchResponse.Entries.Count > 0)
+ {
+ SearchResultEntry entry = searchResponse.Entries[0];
+ Group group = new()
+ {
+ Name = entry.Attributes["cn"][0].ToString(),
+ Type = entry.Attributes["groupType"][0].ToString().GroupType(),
+ DistinguishedName = searchResponse.Entries[0].DistinguishedName
+ };
+ return group;
+ }
+ return null;
+ }
+
+ private string GetPasswordExpiration(string pwdLastSet)
+ {
+ var pwdLastSetDate = DateTime.Parse(pwdLastSet);
+ var passwordExpiration = pwdLastSetDate.AddDays(GetMaxPwdAge());
+ return passwordExpiration.ToString();
+ }
+
+ private double GetMaxPwdAge()
+ {
+ string filter = "(objectClass=domain)";
+ string[] attributesToRetrieve = { "maxPwdAge" };
+
+ SearchRequest searchRequest = new(_ldapConfigs.DistinguishedName, filter, SearchScope.Subtree, attributesToRetrieve);
+ SearchResponse searchResponse = (SearchResponse)_connection.SendRequest(searchRequest);
+
+ if (searchResponse.Entries.Count == 1)
+ {
+ SearchResultEntry entry = searchResponse.Entries[0];
+ long value = long.Parse(entry.Attributes["maxPwdAge"][0].ToString());
+ TimeSpan maxPwdAge = TimeSpan.FromTicks(value);
+ double days = maxPwdAge.TotalDays;
+ return Math.Abs(days);
+ }
+ else
+ {
+ return 42;
+ }
+ }
+}
diff --git a/src/ActiveDirectoryToRestApi/appsettings.Development.json b/src/ActiveDirectoryToRestApi/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/src/ActiveDirectoryToRestApi/appsettings.json b/src/ActiveDirectoryToRestApi/appsettings.json
new file mode 100644
index 0000000..49ba635
--- /dev/null
+++ b/src/ActiveDirectoryToRestApi/appsettings.json
@@ -0,0 +1,16 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "LdapConfigs": {
+ "Server": "192.168.100.25",
+ "DomainName": "AD", // (pre-Windows 2000)
+ "User": "ldapAdmin",
+ "Pass": "Thi$1sMyPassw0rd",
+ "DistinguishedName": "DC=ad,DC=zimbres,DC=com"
+ }
+}