diff --git a/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs b/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f89bb6beb7a7a425bda20d76669b2315ba465083
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+
+namespace Tsi1.Api.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class TenantController : ControllerBase
+ {
+ private readonly ITenantService _tenantService;
+
+ public TenantController(ITenantService tenantService)
+ {
+ _tenantService = tenantService;
+ }
+
+ [Authorize(Roles = UserTypes.UdelarAdmin)]
+ [HttpGet("GetAll")]
+ public async Task<IActionResult> GetAll()
+ {
+ var result = await _tenantService.GetAll();
+
+ if (result.HasError)
+ {
+ return BadRequest(result.Message);
+ }
+
+ return Ok(result.Data);
+ }
+
+ [Authorize(Roles = UserTypes.UdelarAdmin)]
+ [HttpPost("Create")]
+ public async Task<IActionResult> Create(TenantCreateDto newTenant)
+ {
+ var result = await _tenantService.Create(newTenant);
+
+ if (result.HasError)
+ {
+ return BadRequest(result.Message);
+ }
+
+ return Ok(result.Data);
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs b/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs
index bc4b6fa4028264d7031c91412de327d2f4f1c4d3..a26c7605f61b743c49ccff01a57abfe17befab5c 100644
--- a/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs
+++ b/Tsi1.Api/Tsi1.Api/Controllers/UserController.cs
@@ -22,19 +22,40 @@ namespace Tsi1.Api.Controllers
private readonly IJwtAuthManager _jwtAuthManager;
private readonly IUserService _userService;
private readonly IUserTypeService _userTypeService;
+ private readonly ITenantService _tenantService;
- public UserController(IJwtAuthManager jwtAuthManager, IUserService userService, IUserTypeService userTypeService)
+ public UserController(IJwtAuthManager jwtAuthManager, IUserService userService,
+ IUserTypeService userTypeService, ITenantService tenantService)
{
_jwtAuthManager = jwtAuthManager;
_userService = userService;
_userTypeService = userTypeService;
+ _tenantService = tenantService;
}
[AllowAnonymous]
[HttpPost("Login")]
public async Task<IActionResult> Login(LoginRequest request)
{
- var result = await _userService.Authenticate(request.UserName, request.Password, request.TenantId);
+ var resultSplit = request.UserName.Split("@");
+
+ if (resultSplit.Count() != 2)
+ {
+ return BadRequest(ErrorMessages.InvalidUsername);
+ }
+
+ var userName = resultSplit[0];
+
+ var tenantName = resultSplit[1];
+
+ var tenantId = await _tenantService.GetByName(tenantName);
+
+ if (tenantId.HasError)
+ {
+ return BadRequest(tenantId.Message);
+ }
+
+ var result = await _userService.Authenticate(userName, request.Password, tenantId.Data);
if (result.HasError)
{
diff --git a/Tsi1.Api/Tsi1.Api/Models/LoginRequest.cs b/Tsi1.Api/Tsi1.Api/Models/LoginRequest.cs
index 0ce83cfe5fb8a94cd72d654e67cf93019638fdd8..96e87b18d03e7185430f760fb0a5c9caefe6611f 100644
--- a/Tsi1.Api/Tsi1.Api/Models/LoginRequest.cs
+++ b/Tsi1.Api/Tsi1.Api/Models/LoginRequest.cs
@@ -16,9 +16,5 @@ namespace Tsi1.Api.Models
[Required]
[JsonPropertyName("password")]
public string Password { get; set; }
-
- [Required]
- [JsonPropertyName("tenantId")]
- public int TenantId { get; set; }
}
}
diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs
index 6d81c782a6874fe01d7d13bd1692e974f6e06fcc..79120833c4a371a113750cacb92f35edfb71abf9 100644
--- a/Tsi1.Api/Tsi1.Api/Startup.cs
+++ b/Tsi1.Api/Tsi1.Api/Startup.cs
@@ -60,7 +60,8 @@ namespace Tsi1.Api
services.AddScoped<ICourseService, CourseService>();
services.AddScoped<IForumService, ForumService>();
services.AddScoped<IPostService, PostService>();
- services.AddScoped<IPostMessageService, PostMessageService>();
+ services.AddScoped<IPostMessageService, PostMessageService>();
+ services.AddScoped<ITenantService, TenantService>();
services.Configure<MailSettings>(Configuration.GetSection("MailSettings"));
services.AddScoped<IEmailService, EmailService>();
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/TenantCreateDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/TenantCreateDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1906971794cc8058b47049cbc22f6e4a7ab84dd2
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/TenantCreateDto.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+ public class TenantCreateDto
+ {
+ public string Name { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/TenantPreviewDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/TenantPreviewDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..74b8300acafec93c16aac87e34da1af457055766
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/TenantPreviewDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.BusinessLayer.Dtos
+{
+ public class TenantPreviewDto
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
index 880795c242b472b8ec7df424f0bc42ac33b789f7..29bacb3defb6998bd6b4fc0be48b0a31c8dc3fa9 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs
@@ -13,7 +13,8 @@ namespace Tsi1.BusinessLayer.Helpers
public const string StudentCourseAlreadyExists = "El estudiante '{0}' ya se encuentra matriculado en el curso '{1}'";
public const string ProffesorDoesNotExist = "El profesor con Id de usuario: '{0}' no existe";
public const string ProfessorCourseAlreadyExists = "El profesor '{0}' ya es docente del curso '{1}'";
-
+ public const string InvalidUsername = "El nombre de usuario debe ser de la forma: 'usuario@facultad'";
+
public const string ForumDoesNotExist = "El foro con id '{0}' no existe";
public const string DuplicateForumName = "Ya existe un foro con nombre '{0}'";
@@ -29,6 +30,9 @@ namespace Tsi1.BusinessLayer.Helpers
public const string CourseDoesNotExist = "El curso '{0}' no existe";
public const string DuplicateCourseName = "Ya existe un curso con nombre '{0}'";
-
+
+ public const string TenantDoesNotExist = "La Facultad '{0}' no existe";
+ public const string DuplicateTenantName = "Ya existe una Facultad con nombre '{0}'";
+
}
}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
index 8fab13c1e816f8afb5cbf38d9981684b7555ab7b..c00cf1abd7fef1ab43d08a0a6f98a8d3e7ba756c 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs
@@ -26,8 +26,9 @@ namespace Tsi1.BusinessLayer.Helpers
CreateMap<Professor, ProfessorPreviewDto>();
CreateMap<Course, CourseCreateDto>();
CreateMap<Course, CoursePreviewDto>();
+ CreateMap<Tenant, TenantPreviewDto>();
+ CreateMap<Tenant, TenantCreateDto>();
-
CreateMap<ForumCreateDto, Forum>();
CreateMap<ForumPreviewDto, Forum>();
CreateMap<PostCreateDto, Post>();
@@ -41,7 +42,9 @@ namespace Tsi1.BusinessLayer.Helpers
CreateMap<StudentPreviewDto, Student>();
CreateMap<ProfessorPreviewDto, Professor>();
CreateMap<CourseCreateDto, Course>();
- CreateMap<CoursePreviewDto, Course>();
+ CreateMap<CoursePreviewDto, Course>();
+ CreateMap<TenantPreviewDto, Tenant>();
+ CreateMap<TenantCreateDto, Tenant>();
}
}
}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs
index 9fb3b0e8bfd691ed0833bde757acb92626676838..d57a241d16e176b62ab7bdd51b1416cb8b0d42bb 100644
--- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/UserTypes.cs
@@ -9,5 +9,6 @@ namespace Tsi1.BusinessLayer.Helpers
public const string FacultyAdmin = nameof(FacultyAdmin);
public const string Professor = nameof(Professor);
public const string Student = nameof(Student);
+ public const string UdelarAdmin = nameof(UdelarAdmin);
}
}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cbdce15a668d89cf3f0459d98d700a618f959675
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/ITenantService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+
+namespace Tsi1.BusinessLayer.Interfaces
+{
+ public interface ITenantService
+ {
+ Task<ServiceResult<int>> GetByName(string tenantName);
+
+ Task<ServiceResult<List<TenantPreviewDto>>> GetAll();
+
+ Task<ServiceResult<TenantPreviewDto>> Create(TenantCreateDto newTenant);
+
+ //Task<ServiceResult<TenantPreviewDto>> CreateUdelarAdmin(TenantCreateDto newTenant);
+ }
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..fef180d5f1efd31df55b46ce72537a199c10f346
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/TenantService.cs
@@ -0,0 +1,83 @@
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Tsi1.BusinessLayer.Dtos;
+using Tsi1.BusinessLayer.Helpers;
+using Tsi1.BusinessLayer.Interfaces;
+using Tsi1.DataLayer;
+using Tsi1.DataLayer.Entities;
+
+namespace Tsi1.BusinessLayer.Services
+{
+ public class TenantService : ITenantService
+ {
+ private readonly Tsi1Context _context;
+
+ private readonly IMapper _mapper;
+
+ public TenantService(Tsi1Context context, IMapper mapper)
+ {
+ _context = context;
+ _mapper = mapper;
+ }
+
+ public async Task<ServiceResult<List<TenantPreviewDto>>> GetAll()
+ {
+ var result = new ServiceResult<List<TenantPreviewDto>>();
+
+ var tenants = await _context.Tenants.ToListAsync();
+
+ var tenantsDto = _mapper.Map<List<TenantPreviewDto>>(tenants);
+
+ result.Data = tenantsDto;
+
+ return result;
+ }
+
+ public async Task<ServiceResult<int>> GetByName(string tenantName)
+ {
+ var result = new ServiceResult<int>();
+
+ var tenant = await _context.Tenants
+ .FirstOrDefaultAsync(x => x.Name == tenantName);
+
+ if (tenant == null)
+ {
+ result.HasError = true;
+ result.Message = string.Format(ErrorMessages.TenantDoesNotExist, tenantName);
+ return result;
+ }
+
+ result.Data = tenant.Id;
+
+ return result;
+ }
+
+ public async Task<ServiceResult<TenantPreviewDto>> Create(TenantCreateDto newTenant)
+ {
+ var result = new ServiceResult<TenantPreviewDto>();
+
+ var tenant = _mapper.Map<Tenant>(newTenant);
+ _context.Tenants.Add(tenant);
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateException)
+ {
+ result.HasError = true;
+ result.Message = string.Format(ErrorMessages.DuplicateTenantName, newTenant.Name);
+ return result;
+ }
+
+ result.Data = _mapper.Map<TenantPreviewDto>(tenant);
+
+ return result;
+ }
+
+ }
+}