From a92023016d94c4ea378ab15d5199b0e9eb971083 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Mon, 31 Mar 2025 09:28:02 +0200 Subject: [PATCH 1/5] Create `ClaimsService` --- .../Common/Claims/Abstractions/IClaimsService.cs | 9 +++++++++ .../Common/Claims/Services/ClaimsService.cs | 16 ++++++++++++++++ TickAPI/TickAPI/Program.cs | 3 +++ 3 files changed, 28 insertions(+) create mode 100644 TickAPI/TickAPI/Common/Claims/Abstractions/IClaimsService.cs create mode 100644 TickAPI/TickAPI/Common/Claims/Services/ClaimsService.cs diff --git a/TickAPI/TickAPI/Common/Claims/Abstractions/IClaimsService.cs b/TickAPI/TickAPI/Common/Claims/Abstractions/IClaimsService.cs new file mode 100644 index 0000000..7dad5e6 --- /dev/null +++ b/TickAPI/TickAPI/Common/Claims/Abstractions/IClaimsService.cs @@ -0,0 +1,9 @@ +using System.Security.Claims; +using TickAPI.Common.Results.Generic; + +namespace TickAPI.Common.Claims.Abstractions; + +public interface IClaimsService +{ + Result GetEmailFromClaims(IEnumerable claims); +} diff --git a/TickAPI/TickAPI/Common/Claims/Services/ClaimsService.cs b/TickAPI/TickAPI/Common/Claims/Services/ClaimsService.cs new file mode 100644 index 0000000..83da865 --- /dev/null +++ b/TickAPI/TickAPI/Common/Claims/Services/ClaimsService.cs @@ -0,0 +1,16 @@ +using System.Security.Claims; +using TickAPI.Common.Claims.Abstractions; +using TickAPI.Common.Results.Generic; + +namespace TickAPI.Common.Claims.Services; + +public class ClaimsService : IClaimsService +{ + public Result GetEmailFromClaims(IEnumerable claims) + { + var email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value; + if (email == null) + return Result.Failure(StatusCodes.Status400BadRequest, "missing email claim"); + return Result.Success(email); + } +} diff --git a/TickAPI/TickAPI/Program.cs b/TickAPI/TickAPI/Program.cs index 2b0ffca..0c56ab6 100644 --- a/TickAPI/TickAPI/Program.cs +++ b/TickAPI/TickAPI/Program.cs @@ -30,6 +30,8 @@ using TickAPI.Addresses.Abstractions; using TickAPI.Addresses.Repositories; using TickAPI.Addresses.Services; +using TickAPI.Common.Claims.Abstractions; +using TickAPI.Common.Claims.Services; // Builder constants const string allowClientPolicyName = "AllowClient"; @@ -105,6 +107,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); From b5658df6156bc6b4a083337e19793225c90aa7e6 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Mon, 31 Mar 2025 09:38:08 +0200 Subject: [PATCH 2/5] Add tests for `ClaimsService` --- .../Claims/Services/ClaimsServiceTests.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 TickAPI/TickAPI.Tests/Common/Claims/Services/ClaimsServiceTests.cs diff --git a/TickAPI/TickAPI.Tests/Common/Claims/Services/ClaimsServiceTests.cs b/TickAPI/TickAPI.Tests/Common/Claims/Services/ClaimsServiceTests.cs new file mode 100644 index 0000000..f9a0eb3 --- /dev/null +++ b/TickAPI/TickAPI.Tests/Common/Claims/Services/ClaimsServiceTests.cs @@ -0,0 +1,49 @@ +using System.Security.Claims; +using Microsoft.AspNetCore.Http; +using TickAPI.Common.Claims.Abstractions; +using TickAPI.Common.Claims.Services; + +namespace TickAPI.Tests.Common.Claims.Services; + +public class ClaimsServiceTests +{ + private readonly IClaimsService _claimsService; + + public ClaimsServiceTests() + { + _claimsService = new ClaimsService(); + } + + [Fact] + public void GetEmailFromClaims_WhenEmailInClaims_ShouldReturnEmail() + { + // Arrange + var email = "test@gmail.com"; + var claims = new List + { + new Claim(ClaimTypes.Email, email) + }; + + // Act + var result = _claimsService.GetEmailFromClaims(claims); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal(email, result.Value!); + } + + [Fact] + public void GetEmailFromClaims_WhenEmailNotInClaims_ShouldReturnFailure() + { + // Arrange + var claims = new List(); + + // Act + var result = _claimsService.GetEmailFromClaims(claims); + + // Assert + Assert.True(result.IsError); + Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode); + Assert.Equal("missing email claim", result.ErrorMsg); + } +} From f1f985b0090a88c226cb76e391e1648c571684c5 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Mon, 31 Mar 2025 09:39:17 +0200 Subject: [PATCH 3/5] Add `ClaimsService` to `EventController` --- .../Controllers/EventControllerTests.cs | 25 ++++++++-------- .../Events/Controllers/EventController.cs | 29 ++++++++++++------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs b/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs index bde0864..3853bb2 100644 --- a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs @@ -5,11 +5,10 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using TickAPI.Addresses.DTOs.Request; +using TickAPI.Common.Claims.Abstractions; using TickAPI.Events.Controllers; using TickAPI.Events.Abstractions; -using TickAPI.Common.Results; using TickAPI.Common.Results.Generic; -using TickAPI.Organizers.Models; using TickAPI.Events.DTOs.Response; namespace TickAPI.Tests.Events.Controllers; @@ -19,9 +18,7 @@ public class EventControllerTests [Fact] public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess() { - //arrange - string name = "Concert"; string description = "Description of a concert"; DateTime startDate = new DateTime(2025, 5, 1); @@ -38,37 +35,38 @@ public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess() .Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, eventStatus, email)) .ReturnsAsync(Result.Success(new Event())); - var sut = new EventController(eventServiceMock.Object); - var claims = new List { new Claim(ClaimTypes.Email, email) }; - sut.ControllerContext = new ControllerContext + var controllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { User = new ClaimsPrincipal(new ClaimsIdentity(claims)) } }; + + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); + + var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object); + + sut.ControllerContext = controllerContext; // act var res = await sut.CreateEvent(eventDto); // assert - - var result = Assert.IsType>(res); var objectResult = Assert.IsType(result.Result); Assert.Equal(200, objectResult.StatusCode); Assert.Equal("Event created succesfully", objectResult.Value); - } [Fact] public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest() { - //arrange string name = "Concert"; string description = "Description of a concert"; @@ -80,8 +78,10 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest() CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); var eventServiceMock = new Mock(); + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); - var sut = new EventController(eventServiceMock.Object); + var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object); sut.ControllerContext = new ControllerContext { @@ -95,7 +95,6 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest() var res = await sut.CreateEvent(new CreateEventDto(name, description, startDate, endDate, minimumAge, eventStatus, createAddress)); // assert - var result = Assert.IsType>(res); var objectResult = Assert.IsType(result.Result); Assert.Equal(StatusCodes.Status400BadRequest, objectResult.StatusCode); diff --git a/TickAPI/TickAPI/Events/Controllers/EventController.cs b/TickAPI/TickAPI/Events/Controllers/EventController.cs index fb5f65d..f75f70d 100644 --- a/TickAPI/TickAPI/Events/Controllers/EventController.cs +++ b/TickAPI/TickAPI/Events/Controllers/EventController.cs @@ -1,13 +1,12 @@ using Microsoft.AspNetCore.Mvc; using TickAPI.Events.DTOs.Response; using TickAPI.Events.DTOs.Request; -using System.Security.Claims; using TickAPI.Common.Auth.Attributes; using TickAPI.Common.Auth.Enums; -using TickAPI.Events.Models; +using TickAPI.Common.Claims.Abstractions; +using TickAPI.Common.Pagination.Responses; using TickAPI.Events.Abstractions; - namespace TickAPI.Events.Controllers; [ApiController] @@ -17,27 +16,37 @@ namespace TickAPI.Events.Controllers; public class EventController : ControllerBase { private readonly IEventService _eventService; + private readonly IClaimsService _claimsService; - public EventController(IEventService eventService) + public EventController(IEventService eventService, IClaimsService claimsService) { _eventService = eventService; + _claimsService = claimsService; } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] [HttpPost("create-event")] public async Task> CreateEvent([FromBody] CreateEventDto request) { - var email = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value; - if (email == null) - return StatusCode(StatusCodes.Status400BadRequest, "missing email claim"); - + var emailResult = _claimsService.GetEmailFromClaims(User.Claims); + if (emailResult.IsError) + { + return StatusCode(emailResult.StatusCode, emailResult.ErrorMsg); + } + var email = emailResult.Value!; var newEventResult = await _eventService.CreateNewEventAsync(request.Name, request.Description, request.StartDate, request.EndDate, request.MinimumAge, request.CreateAddress, request.EventStatus, email); - if(newEventResult.IsError) + if (newEventResult.IsError) return StatusCode(newEventResult.StatusCode, newEventResult.ErrorMsg); - return Ok("Event created succesfully"); } + + [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] + [HttpGet("get-organizer-events")] + public async Task>> GetOrganizerEvents() + { + throw new NotImplementedException(); + } } \ No newline at end of file From 4336d74ad6705350384e23d3218597f63f7f44eb Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Mon, 31 Mar 2025 09:48:36 +0200 Subject: [PATCH 4/5] Use `ClaimsService` in `CustomerController` --- .../Controllers/CustomerControllerTests.cs | 38 ++++++++++++++----- .../Controllers/CustomerController.cs | 17 ++++++--- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs index 2548884..8e9eadd 100644 --- a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs @@ -5,6 +5,7 @@ using TickAPI.Common.Auth.Abstractions; using TickAPI.Common.Auth.Enums; using TickAPI.Common.Auth.Responses; +using TickAPI.Common.Claims.Abstractions; using TickAPI.Common.Results.Generic; using TickAPI.Customers.Abstractions; using TickAPI.Customers.Controllers; @@ -34,11 +35,14 @@ public async Task GoogleLogin_WhenAuthSuccessAndCustomerExists_ShouldReturnToken var jwtServiceMock = new Mock(); jwtServiceMock.Setup(m => m.GenerateJwtToken(email, UserRole.Customer)) .Returns(Result.Success(jwtToken)); + + var claimsServiceMock = new Mock(); var sut = new CustomerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - customerServiceMock.Object); + customerServiceMock.Object, + claimsServiceMock.Object); // Act var actionResult = await sut.GoogleLogin(new GoogleCustomerLoginDto(accessToken)); @@ -77,10 +81,13 @@ public async Task GoogleLogin_WhenAuthSuccessAndCustomerDoesNotExist_ShouldCreat jwtServiceMock.Setup(m => m.GenerateJwtToken(email, UserRole.Customer)) .Returns(Result.Success(jwtToken)); + var claimsServiceMock = new Mock(); + var sut = new CustomerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - customerServiceMock.Object); + customerServiceMock.Object, + claimsServiceMock.Object); // Act var result = await sut.GoogleLogin(new GoogleCustomerLoginDto( accessToken )); @@ -113,19 +120,13 @@ public async Task AboutMe_WithValidEmailClaim_ShouldReturnCustomerDetails() var googleAuthServiceMock = new Mock(); var jwtServiceMock = new Mock(); - var sut = new CustomerController( - googleAuthServiceMock.Object, - jwtServiceMock.Object, - customerServiceMock.Object); - var claims = new List { new Claim(ClaimTypes.Email, email) }; var identity = new ClaimsIdentity(claims); var claimsPrincipal = new ClaimsPrincipal(identity); - - sut.ControllerContext = new ControllerContext + var controllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { @@ -133,6 +134,18 @@ public async Task AboutMe_WithValidEmailClaim_ShouldReturnCustomerDetails() } }; + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); + + var sut = new CustomerController( + googleAuthServiceMock.Object, + jwtServiceMock.Object, + customerServiceMock.Object, + claimsServiceMock.Object); + + + sut.ControllerContext = controllerContext; + // Act var result = await sut.AboutMe(); @@ -151,10 +164,15 @@ public async Task AboutMe_WithMissingEmailClaim_ShouldReturnBadRequest() var googleAuthServiceMock = new Mock(); var jwtServiceMock = new Mock(); + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); + + var sut = new CustomerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - customerServiceMock.Object); + customerServiceMock.Object, + claimsServiceMock.Object); var claims = new List(); var identity = new ClaimsIdentity(claims); diff --git a/TickAPI/TickAPI/Customers/Controllers/CustomerController.cs b/TickAPI/TickAPI/Customers/Controllers/CustomerController.cs index 5302175..6b5caaf 100644 --- a/TickAPI/TickAPI/Customers/Controllers/CustomerController.cs +++ b/TickAPI/TickAPI/Customers/Controllers/CustomerController.cs @@ -1,8 +1,8 @@ -using System.Security.Claims; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using TickAPI.Common.Auth.Abstractions; using TickAPI.Common.Auth.Attributes; using TickAPI.Common.Auth.Enums; +using TickAPI.Common.Claims.Abstractions; using TickAPI.Customers.Abstractions; using TickAPI.Customers.DTOs.Request; using TickAPI.Customers.DTOs.Response; @@ -16,12 +16,14 @@ public class CustomerController : ControllerBase private readonly IGoogleAuthService _googleAuthService; private readonly IJwtService _jwtService; private readonly ICustomerService _customerService; + private readonly IClaimsService _claimsService; - public CustomerController(IGoogleAuthService googleAuthService, IJwtService jwtService, ICustomerService customerService) + public CustomerController(IGoogleAuthService googleAuthService, IJwtService jwtService, ICustomerService customerService, IClaimsService claimsService) { _googleAuthService = googleAuthService; _jwtService = jwtService; _customerService = customerService; + _claimsService = claimsService; } [HttpPost("google-login")] @@ -52,9 +54,12 @@ public async Task> GoogleLogin([Fro [HttpGet("about-me")] public async Task> AboutMe() { - var email = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value; - if (email == null) - return StatusCode(StatusCodes.Status400BadRequest, "missing email claim"); + var emailResult = _claimsService.GetEmailFromClaims(User.Claims); + if (emailResult.IsError) + { + return StatusCode(emailResult.StatusCode, emailResult.ErrorMsg); + } + var email = emailResult.Value!; var customerResult = await _customerService.GetCustomerByEmailAsync(email); if (customerResult.IsError) From a0b8f99d2db5c7149a0e826200fb2e7c0fc1407c Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Mon, 31 Mar 2025 09:58:25 +0200 Subject: [PATCH 5/5] Use `ClaimsService` in `OrganizerController` --- .../Controllers/OrganizerControllerTests.cs | 89 +++++++++++++------ .../Controllers/OrganizerController.cs | 27 +++--- 2 files changed, 81 insertions(+), 35 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs b/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs index 9560686..5e26e85 100644 --- a/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs @@ -6,6 +6,7 @@ using TickAPI.Common.Auth.Abstractions; using TickAPI.Common.Auth.Enums; using TickAPI.Common.Auth.Responses; +using TickAPI.Common.Claims.Abstractions; using TickAPI.Common.Results; using TickAPI.Common.Results.Generic; using TickAPI.Organizers.Abstractions; @@ -41,10 +42,13 @@ public async Task GoogleLogin_WhenAuthSuccessAndVerifiedOrganizerExists_ShouldRe .Setup(m => m.GenerateJwtToken(email, UserRole.Organizer)) .Returns(Result.Success(jwtToken)); + var claimsServiceMock = new Mock(); + var sut = new OrganizerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - organizerServiceMock.Object + organizerServiceMock.Object, + claimsServiceMock.Object ); // Act @@ -79,10 +83,13 @@ public async Task GoogleLogin_WhenAuthSuccessAndUnverifiedOrganizerExists_Should .Setup(m => m.GenerateJwtToken(email, UserRole.UnverifiedOrganizer)) .Returns(Result.Success(jwtToken)); + var claimsServiceMock = new Mock(); + var sut = new OrganizerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - organizerServiceMock.Object + organizerServiceMock.Object, + claimsServiceMock.Object ); // Act @@ -118,10 +125,13 @@ public async Task .Setup(m => m.GenerateJwtToken(email, UserRole.NewOrganizer)) .Returns(Result.Success(jwtToken)); + var claimsServiceMock = new Mock(); + var sut = new OrganizerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - organizerServiceMock.Object + organizerServiceMock.Object, + claimsServiceMock.Object ); // Act @@ -164,16 +174,11 @@ public async Task CreateOrganizer_WhenCreatingAccountIsSuccessful_ShouldReturnTo jwtServiceMock.Setup(m => m.GenerateJwtToken(email, UserRole.UnverifiedOrganizer)) .Returns(Result.Success(jwtToken)); - var sut = new OrganizerController( - googleAuthServiceMock.Object, - jwtServiceMock.Object, - organizerServiceMock.Object); - var claims = new List { new Claim(ClaimTypes.Email, email) }; - sut.ControllerContext = new ControllerContext + var controllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { @@ -181,6 +186,18 @@ public async Task CreateOrganizer_WhenCreatingAccountIsSuccessful_ShouldReturnTo } }; + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); + + var sut = new OrganizerController( + googleAuthServiceMock.Object, + jwtServiceMock.Object, + organizerServiceMock.Object, + claimsServiceMock.Object); + + + sut.ControllerContext = controllerContext; + // Act var actionResult = await sut.CreateOrganizer(new CreateOrganizerDto(firstName, lastName, displayName)); @@ -198,10 +215,14 @@ public async Task CreateOrganizer_WhenMissingEmailClaim_ShouldReturnBadRequest() var jwtServiceMock = new Mock(); + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); + var sut = new OrganizerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - organizerServiceMock.Object); + organizerServiceMock.Object, + claimsServiceMock.Object); sut.ControllerContext = new ControllerContext { @@ -234,16 +255,18 @@ public async Task VerifyOrganizer_WhenVerificationSuccessful_ShouldReturnOk() .ReturnsAsync(Result.Success()); var jwtServiceMock = new Mock(); + + var claimsServiceMock = new Mock(); var sut = new OrganizerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - organizerServiceMock.Object); + organizerServiceMock.Object, + claimsServiceMock.Object); // Act var actionResult = await sut.VerifyOrganizer(new VerifyOrganizerDto(email)); - // Assert var result = Assert.IsType(actionResult); Assert.Equal(StatusCodes.Status200OK, result.StatusCode); @@ -280,16 +303,11 @@ public async Task AboutMe_WithValidEmailClaim_ShouldReturnOrganizerDetails() var jwtServiceMock = new Mock(); - var sut = new OrganizerController( - googleAuthServiceMock.Object, - jwtServiceMock.Object, - organizerServiceMock.Object); - var claims = new List { new Claim(ClaimTypes.Email, email) }; - sut.ControllerContext = new ControllerContext + var controllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { @@ -297,6 +315,17 @@ public async Task AboutMe_WithValidEmailClaim_ShouldReturnOrganizerDetails() } }; + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); + + var sut = new OrganizerController( + googleAuthServiceMock.Object, + jwtServiceMock.Object, + organizerServiceMock.Object, + claimsServiceMock.Object); + + sut.ControllerContext = controllerContext; + // Act var actionResult = await sut.AboutMe(); @@ -319,10 +348,14 @@ public async Task AboutMe_WithMissingEmailClaim_ShouldReturnBadRequest() var jwtServiceMock = new Mock(); + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); + var sut = new OrganizerController( googleAuthServiceMock.Object, jwtServiceMock.Object, - organizerServiceMock.Object); + organizerServiceMock.Object, + claimsServiceMock.Object); sut.ControllerContext = new ControllerContext { @@ -356,16 +389,11 @@ public async Task AboutMe_WhenOrganizerNotFound_ShouldReturnInternalServerError( var jwtServiceMock = new Mock(); - var sut = new OrganizerController( - googleAuthServiceMock.Object, - jwtServiceMock.Object, - organizerServiceMock.Object); - var claims = new List { new Claim(ClaimTypes.Email, email) }; - sut.ControllerContext = new ControllerContext + var controllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { @@ -373,6 +401,17 @@ public async Task AboutMe_WhenOrganizerNotFound_ShouldReturnInternalServerError( } }; + var claimsServiceMock = new Mock(); + claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); + + var sut = new OrganizerController( + googleAuthServiceMock.Object, + jwtServiceMock.Object, + organizerServiceMock.Object, + claimsServiceMock.Object); + + sut.ControllerContext = controllerContext; + // Act var actionResult = await sut.AboutMe(); diff --git a/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs b/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs index 9465d73..4643556 100644 --- a/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs +++ b/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs @@ -1,8 +1,8 @@ -using System.Security.Claims; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using TickAPI.Common.Auth.Abstractions; using TickAPI.Common.Auth.Attributes; using TickAPI.Common.Auth.Enums; +using TickAPI.Common.Claims.Abstractions; using TickAPI.Common.Results.Generic; using TickAPI.Organizers.Abstractions; using TickAPI.Organizers.DTOs.Request; @@ -17,13 +17,15 @@ public class OrganizerController : ControllerBase private readonly IGoogleAuthService _googleAuthService; private readonly IJwtService _jwtService; private readonly IOrganizerService _organizerService; + private readonly IClaimsService _claimsService; public OrganizerController(IGoogleAuthService googleAuthService, IJwtService jwtService, - IOrganizerService organizerService) + IOrganizerService organizerService, IClaimsService claimsService) { _googleAuthService = googleAuthService; _jwtService = jwtService; _organizerService = organizerService; + _claimsService = claimsService; } [HttpPost("google-login")] @@ -63,9 +65,12 @@ public async Task> GoogleLogin([Fr [HttpPost("create-organizer")] public async Task> CreateOrganizer([FromBody] CreateOrganizerDto request) { - var email = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value; - if (email == null) - return StatusCode(StatusCodes.Status400BadRequest, "missing email claim"); + var emailResult = _claimsService.GetEmailFromClaims(User.Claims); + if (emailResult.IsError) + { + return StatusCode(StatusCodes.Status400BadRequest, emailResult.ErrorMsg); + } + var email = emailResult.Value!; var newOrganizerResult = await _organizerService.CreateNewOrganizerAsync(email, request.FirstName, request.LastName, request.DisplayName); if(newOrganizerResult.IsError) @@ -94,10 +99,12 @@ public async Task VerifyOrganizer([FromBody] VerifyOrganizerDto re [HttpGet("about-me")] public async Task> AboutMe() { - var email = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value; - - if (email == null) - return StatusCode(StatusCodes.Status400BadRequest, "missing email claim"); + var emailResult = _claimsService.GetEmailFromClaims(User.Claims); + if (emailResult.IsError) + { + return StatusCode(StatusCodes.Status400BadRequest, emailResult.ErrorMsg); + } + var email = emailResult.Value!; var organizerResult = await _organizerService.GetOrganizerByEmailAsync(email); if (organizerResult.IsError)