240 lines
8.3 KiB
C#
240 lines
8.3 KiB
C#
using adas_core.Application.Repositories.Interfaces;
|
|
using adas_core.Domain.Enums;
|
|
using adas_core.Domain.Models.AppSettings;
|
|
using adas_core.Domain.Models.Filter;
|
|
using adas_core.Domain.Models.MongoModels;
|
|
using Microsoft.Extensions.Options;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace adas_core.Infrastructure.Repositories;
|
|
|
|
public class UserRepository : MongoRepository<User>, IUserRepository
|
|
{
|
|
private readonly ApiSettings _apiSettings;
|
|
|
|
public UserRepository(IOptions<ApiSettings> apiSettings, IMongoDatabase database) : base(database)
|
|
{
|
|
if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings));
|
|
_apiSettings = apiSettings.Value;
|
|
}
|
|
|
|
public override string GetCollectionName()
|
|
{
|
|
return _apiSettings.Users;
|
|
}
|
|
|
|
public async Task<User?> GetUser(string username, string password)
|
|
{
|
|
var filter = Builders<User>
|
|
.Filter.Eq(p => p.UserName, username) & Builders<User>
|
|
.Filter.Eq(p => p.Password, password);
|
|
var result = await Collection.FindAsync(filter);
|
|
return await result.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<User?> GetById(ObjectId id)
|
|
{
|
|
var filter = Builders<User>
|
|
.Filter.Eq(p => p.Id, id);
|
|
var result = await Collection.FindAsync(filter);
|
|
return await result.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<User?> GetByUserName(string name)
|
|
{
|
|
var filter = Builders<User>
|
|
.Filter.Eq(p => p.UserName, name);
|
|
var result = await Collection.FindAsync(filter);
|
|
return await result.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<User?> GetByUserAndAuthoritesName(string name)
|
|
{
|
|
var matchStage = new BsonDocument("$match", new BsonDocument("userName", name));
|
|
var lookupStage = new BsonDocument("$lookup", new BsonDocument
|
|
{
|
|
{ "from", "authorizations" },
|
|
{ "localField", "_id" },
|
|
{ "foreignField", "userId" },
|
|
{ "as", "Authorization" }
|
|
});
|
|
|
|
var projectStage = new BsonDocument("$project", new BsonDocument
|
|
{
|
|
{ "_id", 1 },
|
|
{ "userName", 1 },
|
|
{ "email", 1 },
|
|
{ "name", 1 },
|
|
{ "Authorization", "$Authorization" },
|
|
{
|
|
"rol", new BsonDocument("$cond", new BsonArray
|
|
{
|
|
new BsonDocument("$eq", new BsonArray { "$Authorization.rol", "Admin" }),
|
|
"$rol",
|
|
"Some"
|
|
})
|
|
}
|
|
});
|
|
|
|
var pipeline = new[]
|
|
{
|
|
matchStage,
|
|
lookupStage,
|
|
projectStage
|
|
};
|
|
|
|
var options = new AggregateOptions { AllowDiskUse = true };
|
|
var result = await Collection.AggregateAsync<User>(pipeline, options);
|
|
var bsonResult = await result.FirstOrDefaultAsync();
|
|
|
|
return bsonResult;
|
|
}
|
|
|
|
public async Task<User?> GetByName(string name)
|
|
{
|
|
var filter = Builders<User>
|
|
.Filter.Eq(p => p.Name, name);
|
|
var result = await Collection.FindAsync(filter);
|
|
return await result.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<User?> UpdateUser(User user, bool updatePass)
|
|
{
|
|
var filter = Builders<User>
|
|
.Filter.Eq(p => p.Id, user.Id);
|
|
var update = Builders<User>.Update
|
|
.Set(u => u.UserName, user.UserName)
|
|
.Set(u => u.Name, user.Name)
|
|
.Set(u => u.Email, user.Email)
|
|
.Set(u => u.LockExpirationDate, user.LockExpirationDate)
|
|
.Set(u => u.LastLogin, user.LastLogin)
|
|
.Set(u => u.IsEnabled, user.IsEnabled);
|
|
|
|
if (updatePass) update = update.Set(u => u.Password, user.Password);
|
|
|
|
await Collection.UpdateOneAsync(filter, update);
|
|
var result = await Collection.Find(filter).FirstOrDefaultAsync();
|
|
return result;
|
|
}
|
|
|
|
public IFindFluent<User, User> GetPaginatedUsers(PaginationFilter filteredRequest)
|
|
{
|
|
// Crear variable con la clase que construye los filtros que necesitamos
|
|
var filterBuilder = Builders<User>.Filter;
|
|
var sort = Builders<User>.Sort.Ascending("userName");
|
|
// Crear una lista de filtros que pueden venir de tu servicio
|
|
var filters = new List<FilterDefinition<User>>();
|
|
if (filteredRequest.FilteredRequest == null) return CreateFindFluent(filters, sort);
|
|
var textFilter = filteredRequest.FilteredRequest?.Text;
|
|
if (!string.IsNullOrEmpty(textFilter))
|
|
{
|
|
var textFilterEscaped = Regex.Escape(textFilter);
|
|
var orFilters = new List<FilterDefinition<User>>
|
|
{
|
|
filterBuilder.Regex(p => p.Name, new BsonRegularExpression(textFilterEscaped, "i")),
|
|
filterBuilder.Regex(p => p.Email, new BsonRegularExpression(textFilterEscaped, "i")),
|
|
filterBuilder.Regex(p => p.UserName, new BsonRegularExpression(textFilterEscaped, "i"))
|
|
};
|
|
filters.Add(filterBuilder.Or(orFilters));
|
|
}
|
|
|
|
var userStatus = filteredRequest.FilteredRequest?.UserStatus;
|
|
filters.Add(filterBuilder.And(GetUserStatusFilter(userStatus)));
|
|
|
|
|
|
if (Enum.TryParse(filteredRequest.FilteredRequest?.UserType, out UserEnum.Type userType))
|
|
{
|
|
GetUserTypeFilter(userType);
|
|
filters.Add(filterBuilder.And(GetUserTypeFilter(userType)));
|
|
}
|
|
|
|
return CreateFindFluent(filters, sort);
|
|
}
|
|
|
|
|
|
public async Task<User> GetOrCreateSystemUser()
|
|
{
|
|
var user = await GetByUserName("System");
|
|
if (user == null)
|
|
{
|
|
var userToInsert = new User
|
|
{
|
|
UserName = "System",
|
|
Name = "System",
|
|
Password = "$2a$12$crWa3EN1izcZBXNc81RzmOlfaYW2TPr2NdDQEWI7RzLTnA0Dd68WG"
|
|
};
|
|
await Collection.InsertOneAsync(userToInsert);
|
|
return userToInsert;
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
public sealed override async Task InsertInitialLoad()
|
|
{
|
|
await GetOrCreateSystemUser();
|
|
}
|
|
|
|
private IFindFluent<User, User> CreateFindFluent(List<FilterDefinition<User>> filters, SortDefinition<User> sort)
|
|
{
|
|
var combinedFilter = filters.Any()
|
|
? Builders<User>.Filter.And(filters)
|
|
: Builders<User>.Filter.Empty; // Filtra todo si no hay filtros
|
|
|
|
return Collection.Find(combinedFilter).Sort(sort);
|
|
}
|
|
|
|
private List<FilterDefinition<User>> GetUserTypeFilter(UserEnum.Type? type)
|
|
{
|
|
var filters = new List<FilterDefinition<User>>();
|
|
var filterBuilder = Builders<User>.Filter;
|
|
|
|
switch (type)
|
|
{
|
|
case UserEnum.Type.Local:
|
|
filters.Add(filterBuilder.Eq(u => u.Type, UserEnum.Type.Local));
|
|
break;
|
|
case UserEnum.Type.Ldap:
|
|
filters.Add(filterBuilder.Eq(u => u.Type, UserEnum.Type.Ldap));
|
|
break;
|
|
}
|
|
|
|
return filters;
|
|
}
|
|
|
|
private List<FilterDefinition<User>> GetUserStatusFilter(StatusEnum.User? status)
|
|
{
|
|
var filters = new List<FilterDefinition<User>>();
|
|
var filterBuilder = Builders<User>.Filter;
|
|
switch (status)
|
|
{
|
|
case StatusEnum.User.Enabled:
|
|
filters.Add(filterBuilder.Or(
|
|
filterBuilder.Eq(u => u.IsEnabled, true),
|
|
filterBuilder.Exists(u => u.IsEnabled, false)
|
|
));
|
|
break;
|
|
case StatusEnum.User.EnabledUnlocked:
|
|
filters.Add(filterBuilder.Or(
|
|
filterBuilder.Eq(u => u.IsEnabled, true),
|
|
filterBuilder.Exists(u => u.IsEnabled, false)
|
|
));
|
|
filters.Add(filterBuilder.Ne(u => u.LockExpirationDate, null));
|
|
break;
|
|
case StatusEnum.User.EnabledLocked:
|
|
filters.Add(filterBuilder.Or(
|
|
filterBuilder.Eq(u => u.IsEnabled, true),
|
|
filterBuilder.Exists(u => u.IsEnabled, false)
|
|
));
|
|
filters.Add(filterBuilder.Eq(u => u.LockExpirationDate, null));
|
|
break;
|
|
case StatusEnum.User.Disabled:
|
|
filters.Add(filterBuilder.Eq(u => u.IsEnabled, false));
|
|
break;
|
|
}
|
|
|
|
return filters;
|
|
}
|
|
} |