628 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			628 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // ***********************************************************************
 | |
| // <copyright file="UserService.cs">
 | |
| //     AgileWebs
 | |
| // </copyright>
 | |
| // ***********************************************************************
 | |
| 
 | |
| using Core.Cerberos.Adapters;
 | |
| using Core.Cerberos.Adapters.Common.Constants;
 | |
| using Core.Cerberos.Adapters.Common.Enums;
 | |
| using Core.Cerberos.Domain.Contexts.Onboarding.Mappers;
 | |
| using Core.Cerberos.Domain.Contexts.Onboarding.Request;
 | |
| using Core.Cerberos.Infraestructure.Caching.Configs;
 | |
| using Core.Cerberos.Infraestructure.Caching.Contracts;
 | |
| using Core.Cerberos.Provider.Contracts;
 | |
| using LSA.Core.Dapper.Service.Caching;
 | |
| using Microsoft.AspNetCore.Http;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using Microsoft.Extensions.Options;
 | |
| using MongoDB.Bson;
 | |
| using MongoDB.Bson.Serialization;
 | |
| using MongoDB.Driver;
 | |
| using System.Text.RegularExpressions;
 | |
| using Core.Blueprint.Storage.Contracts;
 | |
| using Core.Blueprint.Storage.Adapters;
 | |
| 
 | |
| namespace Core.Cerberos.Provider.Providers.Onboarding
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Handles all services and business rules related to <see cref="UserAdapter"/>.
 | |
|     /// </summary>
 | |
|     public class UserService(ILogger<UserService> logger, IHttpContextAccessor httpContextAccessor, ICacheService cacheService,
 | |
|         IOptions<CacheSettings> cacheSettings, IMongoDatabase database, IBlobStorageProvider blobStorageProvider) : IUserService
 | |
|     {
 | |
|         private readonly CacheSettings _cacheSettings = cacheSettings.Value;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a new User.
 | |
|         /// </summary>
 | |
|         /// <param name="newUser">The User to be created.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> CreateUserService(UserRequest newUser)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var entity = newUser.ToAdapter(httpContextAccessor);
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).InsertOneAsync(entity);
 | |
|                 entity.Id = (entity as dynamic ?? "").Id.ToString();
 | |
| 
 | |
|                 return entity;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"CreateUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets an User by identifier.
 | |
|         /// </summary>
 | |
|         /// <param name="id">The User identifier.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> GetUserByIdService(string id)
 | |
|         {
 | |
|             var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetUserByIdService", id);
 | |
|             var cachedData = await cacheService.GetAsync<UserAdapter>(cacheKey);
 | |
| 
 | |
|             if (cachedData is not null) return cachedData;
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.And(
 | |
|                     Builders<UserAdapter>.Filter.Eq("_id", ObjectId.Parse(id)),
 | |
|                     Builders<UserAdapter>.Filter.Eq("status", StatusEnum.Active.ToString())
 | |
|                 );
 | |
| 
 | |
|                 var user = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                             .Find(filter)
 | |
|                             .FirstOrDefaultAsync();
 | |
| 
 | |
|                 var cacheDuration = CacheHelper.GetCacheDuration(_cacheSettings);
 | |
| 
 | |
|                 await cacheService.SetAsync(cacheKey, user, cacheDuration);
 | |
| 
 | |
|                 return user;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"GetUserByIdService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets all the users.
 | |
|         /// </summary>
 | |
|         /// <returns>A <see cref="{Task{IEnumerable{UserAdapter}}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<IEnumerable<UserAdapter>> GetAllUsersService()
 | |
|         {
 | |
|             var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetAllUsersService");
 | |
|             var cachedData = await cacheService.GetAsync<IEnumerable<UserAdapter>>(cacheKey) ?? [];
 | |
| 
 | |
|             if (cachedData.Any()) return cachedData;
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.Eq("status", StatusEnum.Active.ToString());
 | |
| 
 | |
|                 var users = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                             .Find(filter)
 | |
|                             .ToListAsync();
 | |
| 
 | |
|                 var cacheDuration = CacheHelper.GetCacheDuration(_cacheSettings);
 | |
|                 await cacheService.SetAsync(cacheKey, users, cacheDuration);
 | |
| 
 | |
|                 return users;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"GetAllUsersService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets an User by email.
 | |
|         /// </summary>
 | |
|         /// <param name="email">The User email.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> GetUserByEmailService(string? email)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.And(
 | |
|                     Builders<UserAdapter>.Filter.Regex("email", new BsonRegularExpression($"^{Regex.Escape(email ?? "")}$", "i")),
 | |
|                     Builders<UserAdapter>.Filter.Eq("status", StatusEnum.Active.ToString())
 | |
|                 );
 | |
| 
 | |
|                 var user = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                             .Find(filter)
 | |
|                             .FirstOrDefaultAsync();
 | |
| 
 | |
|                 return user;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"GetUserByEmailService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Validates if a users exists by email..
 | |
|         /// </summary>
 | |
|         /// <param name="email">The User email.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> ValidateUserExistenceService(string? email)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.And(
 | |
|                     Builders<UserAdapter>.Filter.Regex("email", new BsonRegularExpression($"^{Regex.Escape(email ?? "")}$", "i")),
 | |
|                     Builders<UserAdapter>.Filter.Eq("status", StatusEnum.Active.ToString())
 | |
|                 );
 | |
| 
 | |
|                 var user = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                             .Find(filter)
 | |
|                             .FirstOrDefaultAsync();
 | |
| 
 | |
|                 return user;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"ValidateUserExistenceService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Deletes an User by id.
 | |
|         /// </summary>
 | |
|         /// <param name="id">The User identifier.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> DeleteUserService(string id)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter
 | |
|                     .Eq("_id", ObjectId.Parse(id));
 | |
| 
 | |
|                 var update = Builders<UserAdapter>.Update
 | |
|                             .Set(v => v.Status, StatusEnum.Inactive);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var deletedUser = await database.GetCollection<UserAdapter>(CollectionNames.User).Find(filter).FirstAsync();
 | |
| 
 | |
|                 return deletedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"DeleteUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Changes the status of the user.
 | |
|         /// </summary>
 | |
|         /// <param name="id">The user identifier.</param>
 | |
|         /// <param name="newStatus">The new status of the user.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> ChangeUserStatusService(string id, StatusEnum newStatus)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter
 | |
|                     .Eq("_id", ObjectId.Parse(id));
 | |
| 
 | |
|                 var update = Builders<UserAdapter>.Update
 | |
|                             .Set(v => v.Status, newStatus)
 | |
|                             .Set(v => v.UpdatedBy, Helper.GetEmail(httpContextAccessor))
 | |
|                             .Set(v => v.UpdatedAt, DateTime.UtcNow);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var updatedUser = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                     .Find(filter)
 | |
|                                     .FirstOrDefaultAsync();
 | |
| 
 | |
|                 return updatedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"ChangeUserStatusService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Updates a User by id.
 | |
|         /// </summary>
 | |
|         /// <param name="entity">The User to be updated.</param>
 | |
|         /// <param name="id">The User identifier.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> UpdateUserService(UserAdapter entity, string id)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter
 | |
|                     .Eq("_id", ObjectId.Parse(id));
 | |
| 
 | |
|                 var update = Builders<UserAdapter>.Update
 | |
|                             .Set(v => v.Email, entity.Email)
 | |
|                             .Set(v => v.Name, entity.Name)
 | |
|                             .Set(v => v.MiddleName, entity.MiddleName)
 | |
|                             .Set(v => v.LastName, entity.LastName)
 | |
|                             .Set(v => v.DisplayName, $"{entity.Name} {entity.MiddleName} {entity.LastName}")
 | |
|                             .Set(v => v.RoleId, entity.RoleId)
 | |
|                             .Set(v => v.Companies, entity.Companies)
 | |
|                             .Set(v => v.Projects, entity.Projects)
 | |
|                             .Set(v => v.Status, entity.Status)
 | |
|                             .Set(v => v.UpdatedBy, Helper.GetEmail(httpContextAccessor))
 | |
|                             .Set(v => v.UpdatedAt, DateTime.UtcNow);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var updatedUser = await GetUserByIdService(id);
 | |
| 
 | |
|                 return updatedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"UpdateUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Logs in the user.
 | |
|         /// </summary>
 | |
|         /// <param name="id">The User identifier.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter?> LogInUserService(string email)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter
 | |
|                     .Regex("email", new BsonRegularExpression($"^{Regex.Escape(email ?? "")}$", "i"));
 | |
| 
 | |
|                 var update = Builders<UserAdapter>.Update
 | |
|                             .Set(v => v.LastLogIn, DateTime.UtcNow);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var user = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                     .Find(filter)
 | |
|                                     .FirstAsync();
 | |
| 
 | |
|                 return user;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"LogInUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Logs out the user's session.
 | |
|         /// </summary>
 | |
|         /// <param name="email">The User email.</param>
 | |
|         /// <returns>A <see cref="{Task{UserAdapter}}"/> representing
 | |
|         /// the asynchronous execution of the service.</returns>
 | |
|         public async Task<UserAdapter> LogOutUserSessionService(string email)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter
 | |
|                     .Regex("email", new BsonRegularExpression($"^{Regex.Escape(email ?? "")}$", "i"));
 | |
| 
 | |
| 
 | |
|                 var update = Builders<UserAdapter>.Update
 | |
|                             .Set(v => v.LastLogOut, DateTime.UtcNow);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var user = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                     .Find(filter)
 | |
|                                     .FirstAsync();
 | |
| 
 | |
|                 return user;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"LogOutUserSessionService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Adds a company to the user's list of companies.
 | |
|         /// </summary>
 | |
|         /// <param name="userId">The identifier of the user to whom the company will be added.</param>
 | |
|         /// <param name="companyId">The identifier of the company to add.</param>
 | |
|         /// <returns>A <see cref="Task{UserAdapter}"/> representing the asynchronous operation, with the updated user object.</returns>
 | |
|         public async Task<UserAdapter> AddCompanyToUserService(string userId, string companyId)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.Eq("_id", ObjectId.Parse(userId));
 | |
|                 var update = Builders<UserAdapter>.Update.AddToSet(v => v.Companies, companyId);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var updatedUser = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                     .Find(filter)
 | |
|                                     .FirstOrDefaultAsync();
 | |
|                 return updatedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"AddCompanyToUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Removes a company from the user's list of companies.
 | |
|         /// </summary>
 | |
|         /// <param name="userId">The identifier of the user from whom the company will be removed.</param>
 | |
|         /// <param name="companyId">The identifier of the company to remove.</param>
 | |
|         /// <returns>A <see cref="Task{UserAdapter}"/> representing the asynchronous operation, with the updated user object.</returns>
 | |
|         public async Task<UserAdapter> RemoveCompanyFromUserService(string userId, string companyId)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.Eq("_id", ObjectId.Parse(userId));
 | |
|                 var update = Builders<UserAdapter>.Update.Pull(v => v.Companies, companyId);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var updatedUser = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                     .Find(filter)
 | |
|                                     .FirstOrDefaultAsync();
 | |
|                 return updatedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"RemoveCompanyFromUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Adds a project to the user's list of projects.
 | |
|         /// </summary>
 | |
|         /// <param name="userId">The identifier of the user to whom the project will be added.</param>
 | |
|         /// <param name="projectId">The identifier of the project to add.</param>
 | |
|         /// <returns>A <see cref="Task{UserAdapter}"/> representing the asynchronous operation, with the updated user object.</returns>
 | |
|         public async Task<UserAdapter> AddProjectToUserService(string userId, string projectId)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.Eq("_id", ObjectId.Parse(userId));
 | |
|                 var update = Builders<UserAdapter>.Update.AddToSet(v => v.Projects, projectId);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var updatedUser = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                      .Find(filter)
 | |
|                                      .FirstOrDefaultAsync();
 | |
|                 return updatedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"AddProjectToUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Removes a project from the user's list of projects.
 | |
|         /// </summary>
 | |
|         /// <param name="userId">The identifier of the user from whom the project will be removed.</param>
 | |
|         /// <param name="projectId">The identifier of the project to remove.</param>
 | |
|         /// <returns>A <see cref="Task{UserAdapter}"/> representing the asynchronous operation, with the updated user object.</returns>
 | |
|         public async Task<UserAdapter> RemoveProjectFromUserService(string userId, string projectId)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var filter = Builders<UserAdapter>.Filter.Eq("_id", ObjectId.Parse(userId));
 | |
|                 var update = Builders<UserAdapter>.Update.Pull(v => v.Projects, projectId);
 | |
| 
 | |
|                 await database.GetCollection<UserAdapter>(CollectionNames.User).UpdateOneAsync(filter, update);
 | |
| 
 | |
|                 var updatedUser = await database.GetCollection<UserAdapter>(CollectionNames.User)
 | |
|                                     .Find(filter)
 | |
|                                     .FirstOrDefaultAsync();
 | |
|                 return updatedUser;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"RemoveProjectFromUserService: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the token adapter for a user.
 | |
|         /// </summary>
 | |
|         /// <param name="email">The user's email.</param>
 | |
|         /// <returns>A <see cref="{Task{TokenAdapter}}"/> representing the asynchronous execution of the service.</returns>
 | |
|         public async Task<TokenAdapter?> GetTokenAdapter(string email)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 var pipeline = new[]
 | |
|                 {
 | |
|                     new BsonDocument("$match", new BsonDocument
 | |
|                     {
 | |
|                         { "email", new BsonDocument
 | |
|                             {
 | |
|                                 { "$regex", $"^{Regex.Escape(email)}$" },
 | |
|                                 { "$options", "i" }
 | |
|                             }
 | |
|                         },
 | |
|                         { "status", StatusEnum.Active.ToString() }
 | |
|                     }),
 | |
| 
 | |
|                     new BsonDocument("$lookup", new BsonDocument
 | |
|                     {
 | |
|                         { "from", "Roles" },
 | |
|                         { "localField", "roleId" },
 | |
|                         { "foreignField", "_id" },
 | |
|                         { "as", "role" }
 | |
|                     }),
 | |
| 
 | |
|                     new BsonDocument("$unwind", "$role"),
 | |
|                     new BsonDocument("$match", new BsonDocument("role.status", StatusEnum.Active.ToString())),
 | |
| 
 | |
|                     new BsonDocument("$addFields", new BsonDocument
 | |
|                     {
 | |
|                         { "role.permissions", new BsonDocument("$map", new BsonDocument
 | |
|                             {
 | |
|                                 { "input", "$role.permissions" },
 | |
|                                 { "as", "perm" },
 | |
|                                 { "in", new BsonDocument("$toObjectId", "$$perm") }
 | |
|                             })
 | |
|                         },
 | |
|                         { "role.modules", new BsonDocument("$map", new BsonDocument
 | |
|                             {
 | |
|                                 { "input", "$role.modules" },
 | |
|                                 { "as", "mod" },
 | |
|                                 { "in", new BsonDocument("$toObjectId", "$$mod") }
 | |
|                             })
 | |
|                         }
 | |
|                     }),
 | |
| 
 | |
|                     new BsonDocument("$lookup", new BsonDocument
 | |
|                     {
 | |
|                         { "from", "Permissions" },
 | |
|                         { "localField", "role.permissions" },
 | |
|                         { "foreignField", "_id" },
 | |
|                         { "as", "permissions" }
 | |
|                     }),
 | |
|                     new BsonDocument("$lookup", new BsonDocument
 | |
|                     {
 | |
|                         { "from", "Modules" },
 | |
|                         { "localField", "role.modules" },
 | |
|                         { "foreignField", "_id" },
 | |
|                         { "as", "modules" }
 | |
|                     }),
 | |
|                     new BsonDocument("$project", new BsonDocument
 | |
|                     {
 | |
|                         { "_id", 1 },
 | |
|                         { "guid", 1 },
 | |
|                         { "email", 1 },
 | |
|                         { "name", 1 },
 | |
|                         { "middleName", 1 },
 | |
|                         { "lastName", 1 },
 | |
|                         { "displayName", 1 },
 | |
|                         { "roleId", 1 },
 | |
|                         { "companies", 1 },
 | |
|                         { "projects", 1 },
 | |
|                         { "lastLogIn", 1 },
 | |
|                         { "lastLogOut", 1 },
 | |
|                         { "createdBy", 1 },
 | |
|                         { "updatedBy", 1 },
 | |
|                         { "status", 1 },
 | |
|                         { "createdAt", 1 },
 | |
|                         { "updatedAt", 1 },
 | |
|                         { "role._id", 1 },
 | |
|                         { "role.name", 1 },
 | |
|                         { "role.description", 1 },
 | |
|                         { "role.applications", 1 },
 | |
|                         { "role.permissions", 1 },
 | |
|                         { "role.modules", 1 },
 | |
|                         { "role.status", 1 },
 | |
|                         { "role.createdAt", 1 },
 | |
|                         { "role.updatedAt", 1 },
 | |
|                         { "role.createdBy", 1 },
 | |
|                         { "role.updatedBy", 1 },
 | |
|                         { "permissions", 1 },
 | |
|                         { "modules", 1 }
 | |
|                     })
 | |
|                 };
 | |
| 
 | |
| 
 | |
|                 var result = await database.GetCollection<BsonDocument>(CollectionNames.User)
 | |
|                     .Aggregate<BsonDocument>(pipeline)
 | |
|                     .FirstOrDefaultAsync();
 | |
| 
 | |
|                 if (result is null) return null;
 | |
| 
 | |
|                 var tokenAdapter = new TokenAdapter
 | |
|                 {
 | |
|                     User = new UserAdapter
 | |
|                     {
 | |
|                         Id = result["_id"]?.ToString() ?? "",
 | |
|                         Guid = result["guid"].AsString,
 | |
|                         Email = result["email"].AsString,
 | |
|                         Name = result["name"].AsString,
 | |
|                         MiddleName = result["middleName"].AsString,
 | |
|                         LastName = result["lastName"].AsString,
 | |
|                         DisplayName = result["displayName"].AsString,
 | |
|                         RoleId = result["roleId"]?.ToString() ?? "",
 | |
|                         Companies = result["companies"].AsBsonArray
 | |
|                             .Select(c => c.AsString)
 | |
|                             .ToArray(),
 | |
|                         Projects = result["projects"].AsBsonArray
 | |
|                             .Select(c => c.AsString)
 | |
|                             .ToArray(),
 | |
|                         LastLogIn = result["lastLogIn"].ToUniversalTime(),
 | |
|                         LastLogOut = result["lastLogOut"].ToUniversalTime(),
 | |
|                         CreatedAt = result["createdAt"].ToUniversalTime(),
 | |
|                         CreatedBy = result["createdBy"].AsString,
 | |
|                         UpdatedAt = result["updatedAt"].ToUniversalTime(),
 | |
|                         UpdatedBy = result["updatedBy"].AsString,
 | |
|                         Status = (StatusEnum)Enum.Parse(typeof(StatusEnum), result["status"].AsString),
 | |
|                     },
 | |
|                     Role = new RoleAdapter
 | |
|                     {
 | |
|                         Id = result["role"]["_id"]?.ToString() ?? "",
 | |
|                         Name = result["role"]["name"].AsString,
 | |
|                         Description = result["role"]["description"].AsString,
 | |
|                         Applications = result["role"]["applications"].AsBsonArray
 | |
|                             .Select(c => (ApplicationsEnum)c.AsInt32)
 | |
|                             .ToArray(),
 | |
|                         Modules = result["role"]["modules"].AsBsonArray
 | |
|                             .Select(c => c.ToString() ?? "")
 | |
|                             .ToArray(),
 | |
|                         Permissions = result["role"]["permissions"].AsBsonArray
 | |
|                             .Select(c => c.ToString() ?? "")
 | |
|                             .ToArray(),
 | |
|                         Status = (StatusEnum)Enum.Parse(typeof(StatusEnum), result["role"]["status"].AsString),
 | |
|                         CreatedAt = result["role"]["createdAt"].ToUniversalTime(),
 | |
|                         UpdatedAt = result["role"]["updatedAt"].ToUniversalTime(),
 | |
|                         CreatedBy = result["role"]["createdBy"].AsString,
 | |
|                         UpdatedBy = result["role"]["updatedBy"].AsString
 | |
|                     },
 | |
|                     Permissions = result["permissions"].AsBsonArray
 | |
|                         .Select(permission => BsonSerializer.Deserialize<PermissionAdapter>(permission.AsBsonDocument))
 | |
|                         .Where(permission => permission.Status == StatusEnum.Active)
 | |
|                         .ToList()
 | |
|                 };
 | |
| 
 | |
|                 return tokenAdapter;
 | |
| 
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 logger.LogError(ex, $"GetTokenAdapter: Error in getting data - {ex.Message}");
 | |
|                 throw new Exception(ex.Message, ex);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | 
