Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(backend): add authentication and booking crud (Abel Mekonen) #331

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<ProjectReference Include="..\CineFlex.Application\CineFlex.Application.csproj" />
<ProjectReference Include="..\CineFlex.Domain\CineFlex.Domain.csproj" />
<ProjectReference Include="..\CineFlex.Persistence\CineFlex.Persistence.csproj" />
<ProjectReference Include="..\CineFlex.Identity\CineFlex.Identity.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using CineFlex.Application.Features.Authentication.CQRS.Commands;
using CineFlex.Application.Features.Authentication.DTOs;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using System.Net;

namespace CineFlex.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AuthController : BaseApiController
{
private readonly IMediator _mediator;

public AuthController(IMediator mediator)
{
_mediator = mediator;
}


[HttpPost("signup")]
public async Task<ActionResult> Register(SignupFormDto signupFormDto)
{
var command = new SignUpCommand { SignupFormDto = signupFormDto };
var response = await _mediator.Send(command);
return HandleResult(response);
}

[HttpPost("signin")]
public async Task<ActionResult> Login(SigninFormDto signinFormDto)
{
var command = new SigninCommand { SigninFormDto = signinFormDto };
var response = await _mediator.Send(command);
return HandleResult(response);
}



}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using CineFlex.Application.Features.Authentication.CQRS.Commands;
using CineFlex.Application.Features.Authentication.DTOs;
using CineFlex.Application.Features.Booking.CQRS.Commands;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace CineFlex.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class BookingController : BaseApiController
{
private readonly IMediator _mediator;

public BookingController(IMediator mediator)
{
_mediator = mediator;
}


[HttpPost("book")]
[Authorize]
public async Task<IActionResult> Book([FromBody] CreateBookingCommand bookCommand)
{
bookCommand.createBookingDto.UserId = User.Claims.FirstOrDefault(c => c.Type == "UserId").Value;
var response = await _mediator.Send(bookCommand);
return Ok(response);
}



}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using CineFlex.Application.Features.Cinema.CQRS.Commands;
using CineFlex.Application.Features.Cinema.CQRS.Queries;
using CineFlex.Application.Features.Cinema.DTO;
using CineFlex.Application.Features.Cinema.Dtos;
using CineFlex.Application.Features.Seats.CQRS.Commands;
using CineFlex.Application.Features.Seats.CQRS.Queries;
using CineFlex.Application.Features.Seats.DTOs;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace CineFlex.API.Controllers
{
public class SeatController : BaseApiController
{
private readonly IMediator _mediator;

public SeatController(IMediator mediator)
{
_mediator = mediator;
}

[HttpGet("GetAll")]
public async Task<ActionResult<List<CinemaDto>>> Get()
{
return HandleResult(await _mediator.Send(new GetAllSeatsQuery()));
}


[HttpPost("CreateSeat")]
[Authorize(Roles = "Admin")]
public async Task<ActionResult> Post([FromBody] CreateSeatDto createSeatDto)
{
var command = new CreateSeatCommand { SeatDto = createSeatDto };
return HandleResult(await _mediator.Send(command));
}


[HttpPut("UpdateSeat")]
[Authorize(Roles = "Admin")]
public async Task<ActionResult> Put([FromBody] UpdateSeatDto updateSeatDto)
{
var command = new UpdateSeatCommand { updateSeatDto = updateSeatDto };
await _mediator.Send(command);
return NoContent();
}

[HttpDelete("{id}")]
[Authorize(Roles = "Admin")]
public async Task<ActionResult> Delete(int id)
{
var command = new DeleteSeatCommand { Id = id };
await _mediator.Send(command);
return NoContent();
}

}
}
2 changes: 2 additions & 0 deletions Backend/backend_assessment/CineFlex/CineFlex.API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using CineFlex.Persistence;
using Microsoft.OpenApi.Models;
using Microsoft.AspNetCore.Identity;
using CineFlex.identity;

var builder = WebApplication.CreateBuilder(args);

// Add services
builder.Services.ConfigureApplicationServices();
builder.Services.ConfigurePersistenceServices(builder.Configuration);
builder.Services.AddHttpContextAccessor();
builder.Services.ConfigureIdentityServices(builder.Configuration);
AddSwaggerDoc(builder.Services);
builder.Services.AddControllers();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
"Microsoft.AspNetCore": "Warning"
}
},
"JwtSettings": {
"Key": "%%%adaaskldfasldkfjalskdf",
"Issuer": "BlogApp.Api",
"Audience": "BlogAppUser",
"DurationInMinutes": 600
},
"AllowedHosts": "*",
"compilationOptions": {
"emitEntryPoint": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

<ItemGroup>
<Folder Include="Mocks\" />
<Folder Include="Seats\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.5.2" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.31" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using CineFlex.Application.Features.Authentication.DTOs;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Contracts.Identity
{
public interface IAuthRepository
{
Task<SignUpResponse> SignUpAsync(SignupFormDto signUpFormDto);
Task<SignInResponse> SignInAsync(SigninFormDto signInFormDto);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using CineFlex.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Contracts.Persistence
{
public interface IBookingRepository : IGenericRepository<BookingEntity>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using CineFlex.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Contracts.Persistence
{
public interface ISeatRepository : IGenericRepository<Seat>
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ namespace CineFlex.Application.Contracts.Persistence
{
public interface IUnitOfWork : IDisposable
{
ISeatRepository SeatRepository { get; }
IMovieRepository MovieRepository { get; }
ICinemaRepository CinemaRepository { get; }
IBookingRepository BookingRepository { get; }
Task<int> Save();

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using CineFlex.Application.Features.Authentication.DTOs;
using CineFlex.Application.Responses;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Features.Authentication.CQRS.Commands
{
public class SigninCommand : IRequest<BaseCommandResponse<SignInResponse>>
{
public SigninFormDto SigninFormDto { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using CineFlex.Application.Features.Authentication.DTOs;
using CineFlex.Application.Responses;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Features.Authentication.CQRS.Commands
{
public class SignUpCommand : IRequest<BaseCommandResponse<SignUpResponse>>
{
public SignupFormDto SignupFormDto { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using CineFlex.Application.Contracts.Identity;
using CineFlex.Application.Features.Authentication.CQRS.Commands;
using CineFlex.Application.Features.Authentication.DTOs;
using CineFlex.Application.Features.Authentication.DTOs.Validators;
using CineFlex.Application.Responses;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Features.Authentication.CQRS.Handlers
{
public class SigninHandler : IRequestHandler<SigninCommand, BaseCommandResponse<SignInResponse>>
{
private readonly IAuthRepository _authenticationRepo;
public SigninHandler(IAuthRepository authRepository)
{
_authenticationRepo = authRepository;
}

public async Task<BaseCommandResponse<SignInResponse>> Handle(SigninCommand request, CancellationToken cancellationToken)
{
var validator = new SignInFormDtoValidators();
var response = new BaseCommandResponse<SignInResponse>();
var validationResult = await validator.ValidateAsync(request.SigninFormDto);
if (validationResult.IsValid == true)
{
try
{
var signInResponse = await _authenticationRepo.SignInAsync(request.SigninFormDto);
response.Success = true;
response.Value = signInResponse;
response.Message = "User Signed In Successfully";
}
catch (Exception e)
{
response.Success = false;
response.Message = "User Sign In Failed";
response.Errors = new List<string>() { e.Message };
}
}
else
{
response.Success = false;
response.Message = "User Sign In Failed";
response.Errors = validationResult.Errors.Select(e => e.ErrorMessage).ToList();
}

return response;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using CineFlex.Application.Contracts.Identity;
using CineFlex.Application.Features.Authentication.CQRS.Commands;
using CineFlex.Application.Features.Authentication.DTOs;
using CineFlex.Application.Features.Authentication.DTOs.Validators;
using CineFlex.Application.Responses;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CineFlex.Application.Features.Authentication.CQRS.Handlers
{
public class SignupHandler : IRequestHandler<SignUpCommand, BaseCommandResponse<SignUpResponse>>
{
private readonly IAuthRepository _authRepository;
public SignupHandler(IAuthRepository authRepository)
{
_authRepository = authRepository;
}

public async Task<BaseCommandResponse<SignUpResponse>> Handle(SignUpCommand request, CancellationToken cancellationToken)
{
var validator = new SignUpFormValidator();
var response = new BaseCommandResponse<SignUpResponse>();
var validationResult = await validator.ValidateAsync(request.SignupFormDto);
if (validationResult.IsValid == true)
{
try
{
var signUpResponse = await _authRepository.SignUpAsync(request.SignupFormDto);
response.Success = true;
response.Value = signUpResponse;
response.Message = "User Registered Successfully";
}
catch (Exception e)
{
response.Success = false;
response.Message = "User Registration Failed";
response.Errors = new List<string>() { e.Message };
}
}
else
{
response.Success = false;
response.Message = "User Registration Failed";
response.Errors = validationResult.Errors.Select(e => e.ErrorMessage).ToList();
}

return response;
}
}
}
Loading