Apigateway/LdapLoginLib/LDAP.cs
2024-04-09 15:06:26 -05:00

206 lines
7.3 KiB
C#

using LdapLoginLib.Data;
using LdapLoginLib.Models;
using System.DirectoryServices.Protocols;
namespace LdapLoginLib
{
public class LDAP
{
private static readonly LdapConfig _ldap = new();
//public LDAP()
//{
// _ldap = new LdapConfig();
//}
public bool Login(string password, string? document = null, string? username = null, string? email = null)
{
using (LdapConnection ldapConnection = _ldap.Connection())
{
try
{
UserInfo userInfo = GetUserInfo(
document: document,
username: username,
email: email);
//Si el usuario está inactivo...
if (userInfo.Activo == false) return false;
// Set LDAP connection options
ldapConnection.SessionOptions.SecureSocketLayer = false;
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.Credential = _ldap.UserCredentials(userInfo.Usuario!, password);
// Attempt to bind (authenticate) the user
ldapConnection.Bind();
return true;
}
catch (LdapException ldapEx)
{
//Console.WriteLine($"Authentication failed: {ldapEx.Message}");
throw new Exception(_getErrorMessage(ldapEx.ErrorCode, ldapEx.Message));
}
catch
{
//Console.WriteLine($"An error occurred: {ex.Message}");
//throw new Exception($"Ocurrió un error: {ex.Message}");
throw;
}
}
}
public static UserInfo GetUserInfo(string? document = null, string? username = null, string? email = null)
{
if (
string.IsNullOrEmpty(document?.Trim()) &&
string.IsNullOrEmpty(username?.Trim()) &&
string.IsNullOrEmpty(email?.Trim())
)
{
throw new Exception("Usuario, correo o documento son requeridos");
}
#region Query String Builder
var ldapFilterArgs = new List<string>();
//uid=APPuser163,ou=services,o=unal.edu.co
if (string.IsNullOrEmpty(document?.Trim()) == false)
{
ldapFilterArgs.Add($"(employeeNumber={document.Trim()})");
}
if (string.IsNullOrEmpty(username?.Trim()) == false)
{
ldapFilterArgs.Add($"(uid={username.Trim()})");
}
if (string.IsNullOrEmpty(email?.Trim()) == false)
{
ldapFilterArgs.Add($"(mail={email.Trim()})");
}
//ldapFilter.Append("ou=People,o=unal.edu.co");
#endregion
using (LdapConnection ldapConnection = _ldap.Connection())
{
try
{
// Admin login
ldapConnection.SessionOptions.SecureSocketLayer = false;
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.Credential = _ldap.AdminCredential();
ldapConnection.Bind();
//Query
string searchBase = $"o=unal.edu.co";
string[] attributesToReturn = {
"uid",
"employeeNumber",
"cn",
"givenName",
"sn",
"mail",
"inetUserStatus",
"o",
"nuip"
};
string ldapFilter = $"(&{String.Join("", ldapFilterArgs.ToArray())})";
SearchRequest searchRequest = new(
searchBase,
ldapFilter,
SearchScope.Subtree,
attributesToReturn
);
searchRequest.SizeLimit = 1; // Buscar solo el primero
SearchResponse searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest);
if (searchResponse != null && searchResponse.Entries.Count > 0)
{
SearchResultEntry entry = searchResponse.Entries[0];
LdapUserInfo ldapUserInfo = new()
{
Uid = entry.Attributes["uid"]?[0].ToString(),
EmployeeNumber = entry.Attributes["employeeNumber"]?[0].ToString(),
Cn = entry.Attributes["cn"]?[0].ToString(),
GivenName = entry.Attributes["givenName"]?[0].ToString(),
Sn = entry.Attributes["sn"]?[0].ToString(),
Mail = entry.Attributes["mail"]?[0].ToString(),
InetUserStatus = entry.Attributes["inetUserStatus"][0].ToString(),
O = entry.Attributes["o"]?[0].ToString(),
MailAlternateAddress = entry.Attributes["mailAlternateAddress"]?[0].ToString(),
//IsActive = entry.Attributes["uid"][0].ToString(),
//NUIP = entry.Attributes["NUIP"]?[0].ToString(),
};
ldapUserInfo.IsActive = _isActive(ldapUserInfo.InetUserStatus);
return (UserInfo)ldapUserInfo;
}
else
{
throw new Exception("Usuario no encontrado o no se recuperaron datos.");
}
}
catch (LdapException ldapEx)
{
Console.WriteLine($"Authentication failed: {ldapEx.Message}");
Console.WriteLine($"Authentication failed: {ldapEx.ErrorCode}");
Console.WriteLine($"Authentication failed: {ldapEx.ServerErrorMessage}");
throw new Exception(ldapEx.Message);
}
catch // (Exception ex)
{
//Console.WriteLine($"An error occurred: {ex.Message}");
//throw new Exception($"Ocurrió un error: {ex.Message}");
throw;
}
}
}
private static bool _isActive(string? inetUserStatus)
{
if (String.IsNullOrEmpty(inetUserStatus?.Trim()) == false)
{
return inetUserStatus.ToLower().Trim() == "active" ? true : false;
}
return false;
}
private static string _getErrorMessage(int errorCode, string errorMessage)
{
// Map LDAP error codes to error messages
switch (errorCode)
{
case 49:
return "Error de credenciales: nombre de usuario o contraseña incorrectos";
case 52:
return "Error de autenticación: cuenta está deshabilitada";
case 81:
return "Error de servidor: no disponible";
default:
return errorMessage;
}
}
}
}