redo
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"email": "sys@t.em",
|
||||
"key": "aa0e0979-99db-42e7-8b60-91c2d055b9d0",
|
||||
"password": "+z1L[oYUupZ>L{4a"
|
||||
"key": "b60e166e-d4a5-416e-a7c9-142d05fb7f31",
|
||||
"password": "8C3,uTÑ<hñ61qQs3"
|
||||
}
|
@@ -2,8 +2,8 @@ using back.DataModels;
|
||||
|
||||
namespace back.DTO;
|
||||
|
||||
public class UserDto
|
||||
public class UserDto
|
||||
{
|
||||
public string Id { get; set; } = null!;
|
||||
public ICollection<Role> Roles { get; set; } = [];
|
||||
public ICollection<RoleDto> Roles { get; set; } = [];
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MCVIngenieros.Transactional.Abstractions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Transactional.Abstractions;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using MCVIngenieros.Transactional.Abstractions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Transactional.Abstractions;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
|
@@ -1,10 +1,16 @@
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
public record PermissionDto
|
||||
{
|
||||
public string Id { get; set; } = null!;
|
||||
}
|
||||
|
||||
[Table("Permissions")]
|
||||
public partial class Permission: IEquatable<Permission>
|
||||
public partial class Permission : IEntity<Permission>
|
||||
{
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public string Id { get; set; } = null!;
|
||||
@@ -26,6 +32,32 @@ public partial class Permission: IEquatable<Permission>
|
||||
Id == other.Id || GetHashCode() == other.GetHashCode();
|
||||
}
|
||||
|
||||
public bool IsNull => this is null;
|
||||
|
||||
public object Clone() => (Permission)MemberwiseClone();
|
||||
|
||||
public int CompareTo(object? obj)
|
||||
{
|
||||
if (obj is null) return 1;
|
||||
if (obj is not Permission other) throw new ArgumentException("Object is not a Person");
|
||||
return CompareTo(other);
|
||||
}
|
||||
|
||||
public int CompareTo(Permission? other)
|
||||
{
|
||||
if (other is null) return 1;
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
return string.Compare(Id, other.Id, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public PermissionDto ToDto()
|
||||
{
|
||||
return new PermissionDto
|
||||
{
|
||||
Id = Id
|
||||
};
|
||||
}
|
||||
|
||||
// Static permissions
|
||||
public static readonly Permission ViewContentPermission = new() { Id = "1", Name = "VIEW_CONTENT", Description = "Permission to view content" };
|
||||
public static readonly Permission LikeContentPermission = new() { Id = "2", Name = "LIKE_CONTENT", Description = "Permission to like content" };
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using MCVIngenieros.Transactional.Abstractions;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Transactional.Abstractions;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
|
@@ -1,10 +1,17 @@
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
public class RoleDto
|
||||
{
|
||||
public string Id { get; set; } = null!;
|
||||
public List<PermissionDto> Permissions { get; set; } = [];
|
||||
}
|
||||
|
||||
[Table("Roles")]
|
||||
public partial class Role : IEquatable<Role>
|
||||
public partial class Role : IEntity<Role>
|
||||
{
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public string Id { get; set; } = null!;
|
||||
@@ -18,7 +25,6 @@ public partial class Role : IEquatable<Role>
|
||||
public virtual ICollection<Permission> Permissions { get; set; } = new HashSet<Permission>();
|
||||
public virtual ICollection<User> Users { get; set; } = [];
|
||||
|
||||
|
||||
public bool IsAdmin() => BaseRoleModel != null ? BaseRoleModel.IsAdmin() : Id == AdminRole.Id;
|
||||
public bool IsContentManager() => BaseRoleModel != null ? BaseRoleModel.IsContentManager() : Id == ContentManagerRole.Id;
|
||||
public bool IsUser() => BaseRoleModel != null ? BaseRoleModel.IsUser() : Id == UserRole.Id;
|
||||
@@ -43,7 +49,7 @@ public partial class Role : IEquatable<Role>
|
||||
BaseRoleModelId = baseRoleModel.Id;
|
||||
foreach (var permission in baseRoleModel.Permissions)
|
||||
{
|
||||
if (!Permissions.Any(p => p.Id == permission.Id))
|
||||
if (!Permissions.Any(p => p.Id == permission.Id))
|
||||
{
|
||||
Permissions.Add(permission);
|
||||
}
|
||||
@@ -62,6 +68,33 @@ public partial class Role : IEquatable<Role>
|
||||
return Id == other.Id || GetHashCode() == other.GetHashCode();
|
||||
}
|
||||
|
||||
public bool IsNull => this is null;
|
||||
|
||||
public object Clone() => (Role)MemberwiseClone();
|
||||
|
||||
public int CompareTo(object? obj)
|
||||
{
|
||||
if (obj is null) return 1;
|
||||
if (obj is not Role other) throw new ArgumentException("Object is not a Person");
|
||||
return CompareTo(other);
|
||||
}
|
||||
|
||||
public int CompareTo(Role? other)
|
||||
{
|
||||
if (other is null) return 1;
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
return string.Compare(Id, other.Id, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public RoleDto ToDto()
|
||||
{
|
||||
return new RoleDto
|
||||
{
|
||||
Id = Id,
|
||||
Permissions = [.. Permissions.Select(p => p.ToDto())]
|
||||
};
|
||||
}
|
||||
|
||||
public static readonly Role UserRole = new(
|
||||
"1", "User", "Role for regular users",
|
||||
[
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using back.DTO;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.DataModels;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class User : IEntity<User>
|
||||
public UserDto ToDto() => new()
|
||||
{
|
||||
Id = Id,
|
||||
Roles = Roles
|
||||
Roles = [.. Roles.Select(r => r.ToDto())]
|
||||
};
|
||||
|
||||
public bool IsAdmin() => Roles.Any(r => r.IsAdmin());
|
||||
@@ -80,7 +80,7 @@ public class User : IEntity<User>
|
||||
password: "",
|
||||
createdAt: DateTime.UtcNow
|
||||
)
|
||||
{
|
||||
{
|
||||
Roles = [Role.AdminRole, Role.ContentManagerRole, Role.UserRole]
|
||||
};
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
using back.ServicesExtensions;
|
||||
using healthchecks;
|
||||
using MCVIngenieros.Healthchecks;
|
||||
|
||||
namespace back;
|
||||
|
||||
@@ -13,11 +13,7 @@ public class Program
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddHealthChecks(options => {
|
||||
options.CacheDuration = TimeSpan.FromMinutes(30);
|
||||
options.Timeout = TimeSpan.FromSeconds(5);
|
||||
options.AssembliesToScan = [typeof(Program).Assembly];
|
||||
}).DiscoverHealthChecks();
|
||||
builder.Services.AddHealthChecksSupport().DiscoverHealthChecks();
|
||||
|
||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
@@ -3,8 +3,8 @@ using System.Text.Json.Serialization;
|
||||
using back.services.engine.SystemUser;
|
||||
using DependencyInjector;
|
||||
using System.Text.Json;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
using Transactional.Implementations.EntityFramework;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using MCVIngenieros.Transactional.Implementations.EntityFramework;
|
||||
|
||||
namespace back.ServicesExtensions;
|
||||
|
||||
|
@@ -19,10 +19,15 @@
|
||||
"EnableSsl": true
|
||||
},
|
||||
"HealthChecksConfigs": {
|
||||
"CacheDuration": "00:30:00",
|
||||
"Timeout": "00:00:05",
|
||||
"AssembliesToScan": [
|
||||
"back"
|
||||
],
|
||||
"Sqlite": {
|
||||
"RetryAttempts" : 2,
|
||||
"Timeout" : "00:05:00",
|
||||
"RetryDelay" : "00:00:10",
|
||||
"RetryAttempts": 2,
|
||||
"Timeout": "00:05:00",
|
||||
"RetryDelay": "00:00:10",
|
||||
"Severity": "Info"
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.1" />
|
||||
<PackageReference Include="Mapster.EFCore" Version="5.1.1" />
|
||||
<PackageReference Include="MCVIngenieros.Healthchecks" Version="0.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
|
||||
@@ -33,7 +34,6 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="9.0.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
<PackageReference Include="Oracle.EntityFrameworkCore" Version="9.23.90" />
|
||||
@@ -48,8 +48,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\nuget\DependencyInjector\DependencyInjector.csproj" />
|
||||
<ProjectReference Include="..\..\nuget\healthchecks\healthchecks.csproj" />
|
||||
<ProjectReference Include="..\..\nuget\Transactional\Transactional.csproj" />
|
||||
<ProjectReference Include="..\..\nuget\Transactional\MCVIngenieros.Transactional.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -5,11 +5,11 @@ VisualStudioVersion = 17.14.36401.2
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "back", "back.csproj", "{392278F3-4B36-47F4-AD31-5FBFCC181AD4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Transactional", "..\..\nuget\Transactional\Transactional.csproj", "{ED76105A-5E6F-4997-86FE-6A7902A2AEBA}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCVIngenieros.Transactional", "..\..\nuget\Transactional\MCVIngenieros.Transactional.csproj", "{ED76105A-5E6F-4997-86FE-6A7902A2AEBA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyInjector", "..\..\nuget\DependencyInjector\DependencyInjector.csproj", "{DBDF84A4-235C-4F29-8626-5BD1DC255970}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "healthchecks", "..\..\nuget\healthchecks\healthchecks.csproj", "{B21E2BEF-17B7-4981-9843-C0CC36D67010}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Presentation", "..\backend\Presentation\Presentation.csproj", "{F1DD9D2A-0467-41EE-B3BB-303F1A0C18D6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -29,10 +29,10 @@ Global
|
||||
{DBDF84A4-235C-4F29-8626-5BD1DC255970}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DBDF84A4-235C-4F29-8626-5BD1DC255970}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DBDF84A4-235C-4F29-8626-5BD1DC255970}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B21E2BEF-17B7-4981-9843-C0CC36D67010}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B21E2BEF-17B7-4981-9843-C0CC36D67010}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B21E2BEF-17B7-4981-9843-C0CC36D67010}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B21E2BEF-17B7-4981-9843-C0CC36D67010}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F1DD9D2A-0467-41EE-B3BB-303F1A0C18D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F1DD9D2A-0467-41EE-B3BB-303F1A0C18D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F1DD9D2A-0467-41EE-B3BB-303F1A0C18D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F1DD9D2A-0467-41EE-B3BB-303F1A0C18D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
44
back/controllers/AuthController.cs
Normal file
44
back/controllers/AuthController.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace back.controllers;
|
||||
|
||||
public class ValidationErrors
|
||||
{
|
||||
public string? Field { get; set; }
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
|
||||
public class ExecutionErrors
|
||||
{
|
||||
public Exception? Exception { get; set; }
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
|
||||
public abstract class ResponseBase
|
||||
{
|
||||
public object? Data { get; set; }
|
||||
public string? Message { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public int StatusCode { get; set; }
|
||||
public ValidationErrors[] ValidationErrors { get; set; }
|
||||
public ExecutionErrors[] ExecutionErrors { get; set; }
|
||||
}
|
||||
|
||||
public record LoginRequest(string Username, string Password);
|
||||
|
||||
[ApiController, Route("api/[controller]")]
|
||||
public class AuthController(IAuthService authService) : ControllerBase
|
||||
{
|
||||
|
||||
private readonly IAuthService _authService = authService;
|
||||
|
||||
[HttpPost, Route("login")]
|
||||
public async Task<IActionResult> Login([FromBody] LoginRequest loginRequest)
|
||||
{
|
||||
// validar que el usuario y la contraseña sean correctos
|
||||
// obtener el token JWT encriptado
|
||||
// obtener el refresh token
|
||||
// devolver el token JWT y el refresh token en los headers de las respuestas
|
||||
// devolver datos del usuario en el body de la respuesta
|
||||
}
|
||||
}
|
@@ -1,8 +1,6 @@
|
||||
using back.DataModels;
|
||||
using back.DTO;
|
||||
using back.services.bussines;
|
||||
using back.services.bussines.UserService;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace back.controllers;
|
||||
@@ -46,14 +44,14 @@ public class UsersController(IUserService user) : ControllerBase
|
||||
if (user == null || string.IsNullOrEmpty(user.Email) || string.IsNullOrEmpty(user.Password))
|
||||
return BadRequest(Errors.BadRequest.Description);
|
||||
|
||||
if (user.Email.Equals(DataModels.User.SystemUser.Email, StringComparison.InvariantCultureIgnoreCase))
|
||||
if (user.Email.Equals(DataModels.User.SystemUser.Email, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (string.IsNullOrEmpty(user.SystemKey))
|
||||
return Unauthorized(Errors.Unauthorized.Description);
|
||||
var systemUser = await _user.ValidateSystemUser(user.Email, user.Password, user.SystemKey, clientId);
|
||||
if (systemUser == null)
|
||||
return Unauthorized(Errors.Unauthorized.Description);
|
||||
return Ok(systemUser.Adapt<UserDto>());
|
||||
return Ok(systemUser.ToDto());
|
||||
}
|
||||
|
||||
var existingUser = await _user.Login(user.Email, user.Password, clientId);
|
||||
@@ -74,7 +72,7 @@ public class UsersController(IUserService user) : ControllerBase
|
||||
// POST api/<UsersController>
|
||||
[HttpPost("[action]")]
|
||||
public async Task<IActionResult> Register(
|
||||
[FromHeader(Name = "X-client-thumbprint")] string clientId,
|
||||
[FromHeader(Name = "X-client-thumbprint")] string clientId,
|
||||
[FromBody] RegisterFromModel user)
|
||||
{
|
||||
if (user == null)
|
||||
|
@@ -1,8 +1,6 @@
|
||||
using HealthChecksConfigsBase = healthchecks.Options.HealthChecksConfigs;
|
||||
namespace back.healthchecks.Options;
|
||||
|
||||
namespace back.healthchecks.Options;
|
||||
|
||||
public partial class HealthChecksConfigs : HealthChecksConfigsBase
|
||||
public partial class HealthChecksConfigs : MCVIngenieros.Healthchecks.Options.HealthChecksConfigs
|
||||
{
|
||||
public const string Sqlite = "Sqlite";
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
using back.Options;
|
||||
using healthchecks;
|
||||
using healthchecks.Abstracts;
|
||||
using back.healthchecks.Options;
|
||||
using back.healthchecks.Options;
|
||||
using back.Options;
|
||||
using MCVIngenieros.Healthchecks;
|
||||
using MCVIngenieros.Healthchecks.Abstracts;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace back.healthchecks;
|
||||
|
||||
public class SqliteHealthCheck(IOptionsMonitor<DatabaseConfig> databaseConfig, IOptionsMonitor<HealthChecksConfigs> healthchecksConfig) : IHealthCheck
|
||||
public class SqliteHealthCheck(IOptionsMonitor<DatabaseConfig> databaseConfig, IOptionsMonitor<HealthChecksConfigs> healthchecksConfig) : HealthCheck
|
||||
{
|
||||
private readonly DatabaseConfig databaseConfig = databaseConfig.Get(DatabaseConfig.DataStorage);
|
||||
private readonly HealthChecksConfigs hcConfig = healthchecksConfig.Get(HealthChecksConfigs.Sqlite);
|
||||
@@ -17,7 +17,7 @@ public class SqliteHealthCheck(IOptionsMonitor<DatabaseConfig> databaseConfig, I
|
||||
public TimeSpan? RetryDelay => hcConfig.RetryDelay ?? TimeSpan.FromSeconds(1);
|
||||
public HealthCheckSeverity? Severity => hcConfig.Severity ?? HealthCheckSeverity.Critical;
|
||||
|
||||
public Task<HealthCheckResult> CheckAsync(CancellationToken cancellationToken = default)
|
||||
public override Task<HealthCheckResult> CheckAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var isHealthy = false;
|
||||
var details = string.Empty;
|
||||
@@ -43,7 +43,7 @@ public class SqliteHealthCheck(IOptionsMonitor<DatabaseConfig> databaseConfig, I
|
||||
details = $"Failed to connect to SQLite database: {ex.Message}";
|
||||
}
|
||||
|
||||
return Task.FromResult(new HealthCheckResult(isHealthy, null)
|
||||
return Task.FromResult(new HealthCheckResult(isHealthy)
|
||||
{
|
||||
Details = details,
|
||||
Severity = isHealthy ? HealthCheckSeverity.Info : HealthCheckSeverity.Critical
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.persistance.blob;
|
||||
|
||||
|
@@ -49,15 +49,6 @@ public partial class DataContext : DbContext
|
||||
relationEstablisher?.EstablishRelation(modelBuilder);
|
||||
});
|
||||
|
||||
//typeof(ISeeder).Assembly.GetExportedTypes()
|
||||
// .Where(t => typeof(ISeeder).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)
|
||||
// .ToList()
|
||||
// .ForEach(seederType =>
|
||||
// {
|
||||
// var seeder = (ISeeder?)Activator.CreateInstance(seederType);
|
||||
// seeder?.Seed(modelBuilder);
|
||||
// });
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,10 @@
|
||||
using back.DataModels;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.persistance.data.repositories.Abstracts;
|
||||
|
||||
public interface IPermissionRepository : IRepository<Permission>, IScoped
|
||||
{
|
||||
Task SeedDefaultPermissions();
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using back.DataModels;
|
||||
using DependencyInjector.Lifetimes;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.persistance.data.repositories.Abstracts;
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
using back.DataModels;
|
||||
using DependencyInjector.Lifetimes;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.persistance.data.repositories.Abstracts;
|
||||
|
||||
public interface IPhotoRepository : IRepository<Photo>, IScoped
|
||||
public interface IPhotoRepository : IRepository<Photo>, IScoped
|
||||
{ }
|
||||
|
@@ -0,0 +1,10 @@
|
||||
using back.DataModels;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.persistance.data.repositories.Abstracts;
|
||||
|
||||
public interface IRoleRepository : IRepository<Role>, IScoped
|
||||
{
|
||||
Task SeedDefaultRoles();
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using back.DataModels;
|
||||
using DependencyInjector.Lifetimes;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.persistance.data.repositories.Abstracts;
|
||||
|
||||
|
34
back/persistance/data/repositories/PermissionRepository.cs
Normal file
34
back/persistance/data/repositories/PermissionRepository.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using back.DataModels;
|
||||
using back.persistance.data.repositories.Abstracts;
|
||||
using MCVIngenieros.Transactional.Implementations.EntityFramework;
|
||||
|
||||
namespace back.persistance.data.repositories;
|
||||
|
||||
public class PermissionRepository(DataContext context) : ReadWriteRepository<Permission>(context), IPermissionRepository
|
||||
{
|
||||
// Implement methods specific to Photo repository if needed
|
||||
public async Task SeedDefaultPermissions()
|
||||
{
|
||||
var defaultPermissions = new List<Permission>
|
||||
{
|
||||
Permission.ViewContentPermission,
|
||||
Permission.LikeContentPermission,
|
||||
Permission.EditContentPermission,
|
||||
Permission.DeleteContentPermission,
|
||||
Permission.CreateContentPermission,
|
||||
Permission.EditUserPermission,
|
||||
Permission.DeleteUserPermission,
|
||||
Permission.DisableUserPermission,
|
||||
Permission.CreateUserPermission,
|
||||
Permission.EditWebConfigPermission
|
||||
};
|
||||
foreach (var permission in defaultPermissions)
|
||||
{
|
||||
if (!Entities.Any(p => p.Id == permission.Id))
|
||||
{
|
||||
Entities.Add(permission);
|
||||
}
|
||||
}
|
||||
await SaveChanges();
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using back.DataModels;
|
||||
using back.persistance.data.repositories.Abstracts;
|
||||
using Transactional.Implementations.EntityFramework;
|
||||
using MCVIngenieros.Transactional.Implementations.EntityFramework;
|
||||
|
||||
namespace back.persistance.data.repositories;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using back.DataModels;
|
||||
using back.persistance.data.repositories.Abstracts;
|
||||
using Transactional.Implementations.EntityFramework;
|
||||
using MCVIngenieros.Transactional.Implementations.EntityFramework;
|
||||
|
||||
namespace back.persistance.data.repositories;
|
||||
|
||||
|
27
back/persistance/data/repositories/RoleRepository.cs
Normal file
27
back/persistance/data/repositories/RoleRepository.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using back.DataModels;
|
||||
using back.persistance.data.repositories.Abstracts;
|
||||
using MCVIngenieros.Transactional.Implementations.EntityFramework;
|
||||
|
||||
namespace back.persistance.data.repositories;
|
||||
|
||||
public class RoleRepository(DataContext context) : ReadWriteRepository<Role>(context), IRoleRepository
|
||||
{
|
||||
// Implement methods specific to Photo repository if needed
|
||||
public async Task SeedDefaultRoles()
|
||||
{
|
||||
var defaultRoles = new List<Role>
|
||||
{
|
||||
Role.AdminRole,
|
||||
Role.UserRole,
|
||||
Role.ContentManagerRole
|
||||
};
|
||||
foreach (var role in defaultRoles)
|
||||
{
|
||||
if (!Entities.Any(p => p.Id == role.Id))
|
||||
{
|
||||
Entities.Add(role);
|
||||
}
|
||||
}
|
||||
await SaveChanges();
|
||||
}
|
||||
}
|
@@ -1,20 +1,22 @@
|
||||
using back.DataModels;
|
||||
using back.persistance.data.repositories.Abstracts;
|
||||
using MCVIngenieros.Transactional.Implementations.EntityFramework;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Transactional.Implementations.EntityFramework;
|
||||
|
||||
namespace back.persistance.data.repositories;
|
||||
|
||||
public class UserRepository(DataContext context) : ReadWriteRepository<User>(context), IUserRepository
|
||||
public class UserRepository(
|
||||
DataContext context
|
||||
) : ReadWriteRepository<User>(context), IUserRepository
|
||||
{
|
||||
public async Task<User?> GetByEmail(string email)
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(email)) return null;
|
||||
return await Entities.FirstOrDefaultAsync(u => u.Email == email);
|
||||
}
|
||||
catch
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -37,26 +39,29 @@ public class UserRepository(DataContext context) : ReadWriteRepository<User>(con
|
||||
public async Task<User?> Login(string email, string password)
|
||||
{
|
||||
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password)) return null;
|
||||
try
|
||||
try
|
||||
{
|
||||
return await Entities.FirstOrDefaultAsync(u => u.Email == email && u.Password == password);
|
||||
return await Entities
|
||||
.Include(u => u.Roles)
|
||||
.ThenInclude(r => r.Permissions)
|
||||
.FirstOrDefaultAsync(u => u.Email == email && u.Password == password);
|
||||
}
|
||||
catch
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> ExistsByEmail(string email)
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(email)) return false;
|
||||
return await Entities.AnyAsync(u => u.Email == email);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,23 +1,23 @@
|
||||
//using back.DataModels;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
using back.DataModels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
//namespace back.persistance.data.seeders;
|
||||
namespace back.persistance.data.seeders;
|
||||
|
||||
//public class PermissionSeeder : ISeeder
|
||||
//{
|
||||
// public void Seed(ModelBuilder modelBuilder)
|
||||
// {
|
||||
// modelBuilder.Entity<Permission>().HasData(
|
||||
// Permission.ViewContentPermission,
|
||||
// Permission.LikeContentPermission,
|
||||
// Permission.EditContentPermission,
|
||||
// Permission.DeleteContentPermission,
|
||||
// Permission.CreateContentPermission,
|
||||
// Permission.EditUserPermission,
|
||||
// Permission.DeleteUserPermission,
|
||||
// Permission.DisableUserPermission,
|
||||
// Permission.CreateUserPermission,
|
||||
// Permission.EditWebConfigPermission
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
public class PermissionSeeder : ISeeder
|
||||
{
|
||||
public void Seed(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Permission>().HasData(
|
||||
Permission.ViewContentPermission,
|
||||
Permission.LikeContentPermission,
|
||||
Permission.EditContentPermission,
|
||||
Permission.DeleteContentPermission,
|
||||
Permission.CreateContentPermission,
|
||||
Permission.EditUserPermission,
|
||||
Permission.DeleteUserPermission,
|
||||
Permission.DisableUserPermission,
|
||||
Permission.CreateUserPermission,
|
||||
Permission.EditWebConfigPermission
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,16 +1,16 @@
|
||||
//using back.DataModels;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
using back.DataModels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
//namespace back.persistance.data.seeders;
|
||||
namespace back.persistance.data.seeders;
|
||||
|
||||
//public class RoleSeeder : ISeeder
|
||||
//{
|
||||
// public void Seed(ModelBuilder modelBuilder)
|
||||
// {
|
||||
// modelBuilder.Entity<Permission>().HasData(
|
||||
// new Role { Id = "1", Name = "User", Description = "Role for regular users", BaseRoleModelId = null },
|
||||
// new Role { Id = "2", Name = "Content Manager", Description = "Role for managing content", BaseRoleModelId = "1" },
|
||||
// new Role { Id = "3", Name = "Admin", Description = "Administrator role with full permissions", BaseRoleModelId = "2" }
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
public class RoleSeeder : ISeeder
|
||||
{
|
||||
public void Seed(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Permission>().HasData(
|
||||
new Role { Id = "1", Name = "User", Description = "Role for regular users", BaseRoleModelId = null },
|
||||
new Role { Id = "2", Name = "Content Manager", Description = "Role for managing content", BaseRoleModelId = "1" },
|
||||
new Role { Id = "3", Name = "Admin", Description = "Administrator role with full permissions", BaseRoleModelId = "2" }
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,14 +1,14 @@
|
||||
using back.DataModels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
//using back.DataModels;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace back.persistance.data.seeders;
|
||||
//namespace back.persistance.data.seeders;
|
||||
|
||||
public class SystemUserSeeder : ISeeder
|
||||
{
|
||||
public void Seed(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Permission>().HasData(
|
||||
User.SystemUser
|
||||
);
|
||||
}
|
||||
}
|
||||
//public class SystemUserSeeder : ISeeder
|
||||
//{
|
||||
// public void Seed(ModelBuilder modelBuilder)
|
||||
// {
|
||||
// modelBuilder.Entity<Permission>().HasData(
|
||||
// User.SystemUser
|
||||
// );
|
||||
// }
|
||||
//}
|
@@ -1,6 +1,6 @@
|
||||
using back.DataModels;
|
||||
using back.DTO;
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.bussines.PhotoService;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
using back.DataModels;
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.bussines.UserService;
|
||||
|
||||
|
@@ -68,7 +68,7 @@ public class UserService(
|
||||
return existingUser;
|
||||
}
|
||||
|
||||
public async Task<User?> Login(string email, string decryptedPass)
|
||||
public async Task<User?> Login(string email, string decryptedPass)
|
||||
{
|
||||
var salt = await _repository.GetUserSaltByEmail(email);
|
||||
var hashedPassword = _cryptoService.HashPassword(decryptedPass, salt);
|
||||
@@ -136,6 +136,7 @@ public class UserService(
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await Login(user.Email!, decryptedPassword);
|
||||
var loggedUser = await Login(user.Email!, decryptedPassword);
|
||||
return loggedUser;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.engine.Crypto;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.engine.ImageResizer;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.engine.PasswordGenerator;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.engine.SystemUser;
|
||||
|
||||
|
@@ -4,8 +4,8 @@ using back.persistance.data;
|
||||
using back.persistance.data.repositories.Abstracts;
|
||||
using back.services.engine.Crypto;
|
||||
using back.services.engine.PasswordGenerator;
|
||||
using MCVIngenieros.Transactional.Abstractions.Interfaces;
|
||||
using System.Text.Json;
|
||||
using Transactional.Abstractions.Interfaces;
|
||||
|
||||
namespace back.services.engine.SystemUser;
|
||||
|
||||
@@ -14,17 +14,20 @@ public class SystemUserGenerator(
|
||||
JsonSerializerOptions jsonSerializerOptions,
|
||||
IUserRepository userRepository,
|
||||
IPersonRepository personRepository,
|
||||
IRoleRepository roleRepository,
|
||||
IPermissionRepository permissionRepository,
|
||||
ICryptoService cryptoService,
|
||||
IBlobStorageService blobStorageService,
|
||||
IPasswordGenerator passwordGenerator) : ISystemUserGenerator
|
||||
{
|
||||
public async Task GenerateAsync()
|
||||
{
|
||||
var systemKey = new SystemKey() {
|
||||
var systemKey = new SystemKey()
|
||||
{
|
||||
Password = passwordGenerator.Generate(16),
|
||||
};
|
||||
var systemKeyJson = JsonSerializer.Serialize(systemKey, options: jsonSerializerOptions);
|
||||
|
||||
|
||||
using Stream stream = new MemoryStream(new System.Text.UTF8Encoding(true).GetBytes(systemKeyJson));
|
||||
|
||||
await blobStorageService.Delete("systemkey.lock");
|
||||
@@ -42,11 +45,13 @@ public class SystemUserGenerator(
|
||||
{
|
||||
await transactional.DoTransaction(async () =>
|
||||
{
|
||||
await permissionRepository.SeedDefaultPermissions();
|
||||
await roleRepository.SeedDefaultRoles();
|
||||
await personRepository.Insert(Person.SystemPerson);
|
||||
await userRepository.Insert(User.SystemUser);
|
||||
});
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
await userRepository.Update(User.SystemUser);
|
||||
await userRepository.SaveChanges();
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using DependencyInjector.Lifetimes;
|
||||
using DependencyInjector.Abstractions.Lifetimes;
|
||||
|
||||
namespace back.services.engine.mailing;
|
||||
|
||||
|
8
backend/Presentation/Controllers/AuthController.cs
Normal file
8
backend/Presentation/Controllers/AuthController.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Presentation.Controllers;
|
||||
|
||||
public class AuthController : Controller
|
||||
{
|
||||
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
namespace Presentation.Infraestructura.Responses;
|
||||
|
||||
public sealed class ExecutionError(string message)
|
||||
{
|
||||
public string Message { get; set; } = message;
|
||||
}
|
29
backend/Presentation/Infraestructura/Responses/Response.cs
Normal file
29
backend/Presentation/Infraestructura/Responses/Response.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Net;
|
||||
|
||||
namespace Presentation.Infraestructura.Responses;
|
||||
|
||||
public sealed class Response<T>
|
||||
{
|
||||
public bool IsSuccess { get; set; }
|
||||
public HttpStatusCode StatusCode { get; set; }
|
||||
public T? Data { get; set; }
|
||||
public ValidationError[]? ValidationErrors { get; set; }
|
||||
public ExecutionError[]? ExecutionErrors { get; set; }
|
||||
|
||||
public static Response<T> Success(T result, HttpStatusCode statusCode = HttpStatusCode.OK) =>
|
||||
new()
|
||||
{
|
||||
IsSuccess = true,
|
||||
StatusCode = statusCode,
|
||||
Data = result
|
||||
};
|
||||
|
||||
public static Response<T> Failure(HttpStatusCode statusCode = HttpStatusCode.InternalServerError, ValidationError[]? validationErrors = null, ExecutionError[]? executionErrors = null) =>
|
||||
new()
|
||||
{
|
||||
IsSuccess = false,
|
||||
StatusCode = statusCode,
|
||||
ValidationErrors = validationErrors,
|
||||
ExecutionErrors = executionErrors
|
||||
};
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
namespace Presentation.Infraestructura.Responses;
|
||||
|
||||
public sealed class ValidationError(string fieldName, string message)
|
||||
{
|
||||
public string Field { get; set; } = fieldName;
|
||||
public string Message { get; set; } = message;
|
||||
}
|
34
backend/Presentation/Presentation.csproj
Normal file
34
backend/Presentation/Presentation.csproj
Normal file
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8" />
|
||||
<PackageReference Include="OpenTelemetry" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Api" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Api.ProviderBuilderExtensions" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" />
|
||||
<PackageReference Include="Serilog.Enrichers.Process" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.OpenTelemetry" Version="4.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
96
backend/Presentation/Program.cs
Normal file
96
backend/Presentation/Program.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.OpenTelemetry;
|
||||
|
||||
namespace Presentation
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Configura Serilog como logger global antes de crear el builder
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Console()
|
||||
.WriteTo.OpenTelemetry(options =>
|
||||
{
|
||||
options.Endpoint = "http://localhost:4317"; // OTLP endpoint
|
||||
options.Protocol = OtlpProtocol.Grpc;
|
||||
options.ResourceAttributes = new Dictionary<string, object>
|
||||
{
|
||||
["service.name"] = "mmorales.photo-backend"
|
||||
};
|
||||
})
|
||||
.CreateLogger();
|
||||
|
||||
try
|
||||
{
|
||||
Log.Information("Starting up");
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Host.UseSerilog(); // Usa Serilog como proveedor de logs por defecto
|
||||
|
||||
builder.Services.AddProblemDetails(options =>
|
||||
options.CustomizeProblemDetails =
|
||||
ctx => ctx.ProblemDetails.Extensions.Add("traceId", ctx.HttpContext.TraceIdentifier)
|
||||
);
|
||||
builder.Services.AddOpenTelemetry()
|
||||
.WithTracing(tracerProviderBuilder =>
|
||||
{
|
||||
tracerProviderBuilder
|
||||
.SetResourceBuilder(ResourceBuilder.CreateDefault()
|
||||
.AddService(builder.Environment.ApplicationName))
|
||||
.AddAspNetCoreInstrumentation() // Traza todas las peticiones HTTP entrantes
|
||||
.AddHttpClientInstrumentation() // Traza las llamadas HttpClient salientes
|
||||
.AddOtlpExporter(opt =>
|
||||
{
|
||||
opt.Endpoint = new Uri("http://localhost:4317"); // Direcci<63>n del colector OTel
|
||||
})
|
||||
.AddConsoleExporter(); // Exporta trazas tambi<62>n a consola para desarrollo
|
||||
});
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
var app = builder.Build();
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler();
|
||||
app.UseHsts();
|
||||
}
|
||||
app.UseStatusCodePages();
|
||||
|
||||
app.UseAuthentication(); // Habilita autenticaci<63>n
|
||||
app.UseAuthorization(); // Habilita autorizaci<63>n
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.MapOpenApi();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Fatal(ex, "Application start-up failed");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
backend/Presentation/Properties/launchSettings.json
Normal file
23
backend/Presentation/Properties/launchSettings.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://localhost:5101",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:7265;http://localhost:5101",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
backend/Presentation/appsettings.Development.json
Normal file
8
backend/Presentation/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
9
backend/Presentation/appsettings.json
Normal file
9
backend/Presentation/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
@@ -1,3 +1,6 @@
|
||||
<div class="admin-panel-link">
|
||||
<a href="/admin">Admin</a>
|
||||
</div>
|
||||
<svg-button
|
||||
label="Panel de Administración"
|
||||
routerLink="/admin"
|
||||
text="Panel de Administración"
|
||||
icon="assets/icons/book-section-svgrepo-com.svg"
|
||||
></svg-button>
|
||||
|
Before Width: | Height: | Size: 67 B After Width: | Height: | Size: 169 B |
@@ -1,11 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { SvgButton } from '../../../utils/svg-button/svg-button';
|
||||
|
||||
@Component({
|
||||
selector: 'admin-panel-link',
|
||||
imports: [],
|
||||
imports: [SvgButton],
|
||||
templateUrl: './admin-panel-link.html',
|
||||
styleUrl: './admin-panel-link.scss'
|
||||
styleUrl: './admin-panel-link.scss',
|
||||
})
|
||||
export class AdminPanelLink {
|
||||
|
||||
}
|
||||
export class AdminPanelLink {}
|
||||
|
@@ -1,3 +1,6 @@
|
||||
<div class="content-manager-panel-link">
|
||||
<a href="/content-manager">Contenido</a>
|
||||
</div>
|
||||
<svg-button
|
||||
label="Panel de Contenido"
|
||||
routerLink="/content-manager"
|
||||
text="Panel de Contenido"
|
||||
icon="assets/icons/book-section-svgrepo-com.svg"
|
||||
></svg-button>
|
||||
|
Before Width: | Height: | Size: 91 B After Width: | Height: | Size: 167 B |
@@ -1,11 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { SvgButton } from '../../../utils/svg-button/svg-button';
|
||||
|
||||
@Component({
|
||||
selector: 'content-manager-panel-link',
|
||||
imports: [],
|
||||
imports: [SvgButton],
|
||||
templateUrl: './content-manager-panel-link.html',
|
||||
styleUrl: './content-manager-panel-link.scss'
|
||||
styleUrl: './content-manager-panel-link.scss',
|
||||
})
|
||||
export class ContentManagerPanelLink {
|
||||
|
||||
}
|
||||
export class ContentManagerPanelLink {}
|
||||
|
@@ -12,7 +12,6 @@ import { OnInit } from '@angular/core';
|
||||
import { userModel } from '../../../models/userModel';
|
||||
import { ServicesLink } from '../services-link/services-link';
|
||||
import { Router, NavigationEnd } from '@angular/router';
|
||||
import { R } from '@angular/cdk/keycodes';
|
||||
|
||||
@Component({
|
||||
selector: 'custom-header',
|
||||
|
@@ -1,3 +1,6 @@
|
||||
<div class="user-galleries-link">
|
||||
<a href="/galeria">Galería</a>
|
||||
</div>
|
||||
<svg-button
|
||||
label="Galerías"
|
||||
routerLink="/my-galleries"
|
||||
text="Galerías"
|
||||
icon="assets/icons/book-section-svgrepo-com.svg"
|
||||
></svg-button>
|
||||
|
Before Width: | Height: | Size: 75 B After Width: | Height: | Size: 146 B |
@@ -1,11 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, inject, signal } from '@angular/core';
|
||||
import { SvgButton } from '../../../utils/svg-button/svg-button';
|
||||
|
||||
@Component({
|
||||
selector: 'user-galleries-link',
|
||||
imports: [],
|
||||
imports: [SvgButton],
|
||||
templateUrl: './user-galleries-link.html',
|
||||
styleUrl: './user-galleries-link.scss'
|
||||
styleUrl: './user-galleries-link.scss',
|
||||
})
|
||||
export class UserGalleriesLink {
|
||||
|
||||
}
|
||||
export class UserGalleriesLink {}
|
||||
|
@@ -39,9 +39,10 @@ export class userService {
|
||||
systemKey: encryptedSystemKey,
|
||||
})
|
||||
.then((response) => {
|
||||
const { jwt, refresh, usermodel } = response.data;
|
||||
localStorage.setItem('jwt', jwt);
|
||||
localStorage.setItem('refresh', refresh);
|
||||
const { id, roles } = response.data;
|
||||
const usermodel = new userModel(id, roles, true);
|
||||
// localStorage.setItem('jwt', jwt);
|
||||
// localStorage.setItem('refresh', refresh);
|
||||
this.setUser(usermodel);
|
||||
return usermodel;
|
||||
});
|
||||
|
@@ -8,6 +8,13 @@ export class roleModel {
|
||||
public permissions: permissionModel[] = [],
|
||||
public baseRoleModel: roleModel | null = null
|
||||
) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.permissions = [];
|
||||
for (const p of permissions) {
|
||||
this.permissions.push(new permissionModel(p.id, '', ''));
|
||||
}
|
||||
if (baseRoleModel) {
|
||||
this.permissions = baseRoleModel.permissions.concat(this.permissions);
|
||||
}
|
||||
|
@@ -11,47 +11,59 @@ enum SigningMethods {
|
||||
Microsoft = 'microsoft',
|
||||
}
|
||||
|
||||
class userModel extends personModel {
|
||||
class userModel {
|
||||
constructor(
|
||||
public override id: string,
|
||||
public email: string,
|
||||
public password: string,
|
||||
public override name: string,
|
||||
public id: string,
|
||||
public role: roleModel[],
|
||||
public createdAt: Date,
|
||||
public updatedAt: Date,
|
||||
public isLoggedIn: boolean,
|
||||
public preferredSigningMethod: SigningMethods = SigningMethods.Password
|
||||
public isLoggedIn: boolean
|
||||
) {
|
||||
super({
|
||||
id,
|
||||
name,
|
||||
profilePicture: null,
|
||||
avatar: null,
|
||||
socialMedia: null,
|
||||
});
|
||||
this.id = id;
|
||||
for (const r of role) {
|
||||
this.role.push(new roleModel(r.id, '', '', r.permissions, null));
|
||||
}
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
}
|
||||
|
||||
// constructor(
|
||||
// public override id: string,
|
||||
// public email: string,
|
||||
// public password: string,
|
||||
// public override name: string,
|
||||
// public role: roleModel[],
|
||||
// public createdAt: Date,
|
||||
// public updatedAt: Date,
|
||||
// public isLoggedIn: boolean,
|
||||
// public preferredSigningMethod: SigningMethods = SigningMethods.Password
|
||||
// ) {
|
||||
// super({
|
||||
// id,
|
||||
// name,
|
||||
// profilePicture: null,
|
||||
// avatar: null,
|
||||
// socialMedia: null,
|
||||
// });
|
||||
// }
|
||||
|
||||
get isAdmin(): boolean {
|
||||
return this.role.some((role) => role.isAdmin);
|
||||
return this.role.some((r) => r.isAdmin);
|
||||
}
|
||||
|
||||
get isContentManager(): boolean {
|
||||
return this.role.some((role) => role.isContentManager);
|
||||
return this.role.some((r) => r.isContentManager);
|
||||
}
|
||||
|
||||
get isUser(): boolean {
|
||||
return this.role.some((role) => role.isUser);
|
||||
return this.role.some((r) => r.isUser);
|
||||
}
|
||||
|
||||
public static readonly DefaultUser: userModel = new userModel(
|
||||
'0',
|
||||
'default@example.com',
|
||||
'',
|
||||
'Default User',
|
||||
// 'default@example.com',
|
||||
// '',
|
||||
// 'Default User',
|
||||
[roleModel.UserRole],
|
||||
new Date(),
|
||||
new Date(),
|
||||
// new Date(),
|
||||
// new Date(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user