Setup wallet and transaction retrieval, better swagger docs, and proper dtos
This commit is contained in:
@ -23,6 +23,8 @@ using System.Threading.Tasks;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using IO.Swagger.Services;
|
using IO.Swagger.Services;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using AutoMapper;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace IO.Swagger.Controllers
|
namespace IO.Swagger.Controllers
|
||||||
{
|
{
|
||||||
@ -34,17 +36,20 @@ namespace IO.Swagger.Controllers
|
|||||||
{
|
{
|
||||||
private readonly IUserRepository repository;
|
private readonly IUserRepository repository;
|
||||||
private readonly JwtService jwt;
|
private readonly JwtService jwt;
|
||||||
|
private readonly IMapper mapper;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The controller for the authotization endpoints
|
/// The controller for the authotization endpoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="repository"></param>
|
/// <param name="repository"></param>
|
||||||
/// <param name="jwt"></param>
|
/// <param name="jwt"></param>
|
||||||
|
/// <param name="mapper"></param>
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
public AuthApiController(IUserRepository repository, JwtService jwt)
|
public AuthApiController(IUserRepository repository, JwtService jwt, IMapper mapper)
|
||||||
{
|
{
|
||||||
this.repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
this.repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||||
this.jwt = jwt ?? throw new ArgumentNullException(nameof(jwt));
|
this.jwt = jwt ?? throw new ArgumentNullException(nameof(jwt));
|
||||||
|
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -57,13 +62,15 @@ namespace IO.Swagger.Controllers
|
|||||||
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||||
[ValidateModelState]
|
[ValidateModelState]
|
||||||
[SwaggerOperation("GetUserDetails")]
|
[SwaggerOperation("GetUserDetails")]
|
||||||
|
[ProducesResponseType(typeof(UserDto), 200)]
|
||||||
|
[ProducesResponseType(401)]
|
||||||
public virtual async Task<IActionResult> GetUserDetails()
|
public virtual async Task<IActionResult> GetUserDetails()
|
||||||
{
|
{
|
||||||
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||||
if (!int.TryParse(userIdString, out int userId))
|
if (!int.TryParse(userIdString, out int userId))
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
var user = await repository.RetrieveUser(userId);
|
var user = await repository.RetrieveUser(userId);
|
||||||
return user == null ? NoContent() : Ok(user);
|
return Ok(mapper.Map<UserDto>(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -71,17 +78,21 @@ namespace IO.Swagger.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="body"></param>
|
/// <param name="body"></param>
|
||||||
/// <response code="200">Logged in successfully</response>
|
/// <response code="200">Logged in successfully</response>
|
||||||
|
/// <response code="400">Bad Request</response>
|
||||||
/// <response code="401">Unauthorized</response>
|
/// <response code="401">Unauthorized</response>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("/v1/api/auth/login")]
|
[Route("/v1/api/auth/login")]
|
||||||
[ValidateModelState]
|
[ValidateModelState]
|
||||||
[SwaggerOperation("LoginUser")]
|
[SwaggerOperation("LoginUser")]
|
||||||
|
[ProducesResponseType(typeof(TokenDto), 200)]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<string>), 400)]
|
||||||
|
[ProducesResponseType(401)]
|
||||||
public virtual async Task<IActionResult> LoginUser([FromBody]AuthLoginBody body)
|
public virtual async Task<IActionResult> LoginUser([FromBody]AuthLoginBody body)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
||||||
var user = await repository.LoginUser(body);
|
var user = await repository.LoginUser(body);
|
||||||
return user == null ? Unauthorized() : Ok(new { token = jwt.GenerateJwt(user.Id) });
|
return user == null ? Unauthorized() : Ok(new TokenDto{ Token = jwt.GenerateJwt(user.Id) });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -96,13 +107,16 @@ namespace IO.Swagger.Controllers
|
|||||||
[ValidateModelState]
|
[ValidateModelState]
|
||||||
|
|
||||||
[SwaggerOperation("RegisterUser")]
|
[SwaggerOperation("RegisterUser")]
|
||||||
|
[ProducesResponseType(typeof(TokenDto), 200)]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<string>), 400)]
|
||||||
|
[ProducesResponseType(409)]
|
||||||
public async Task<IActionResult> RegisterUser([FromBody]AuthRegisterBody body)
|
public async Task<IActionResult> RegisterUser([FromBody]AuthRegisterBody body)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
||||||
|
|
||||||
var user = await repository.RegisterUser(body);
|
var user = await repository.RegisterUser(body);
|
||||||
return user == null ? StatusCode(409) : Ok(new { token = jwt.GenerateJwt(user.Id) });
|
return user == null ? StatusCode(409) : Ok(new TokenDto{ Token = jwt.GenerateJwt(user.Id) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,10 @@ namespace IO.Swagger.Controllers
|
|||||||
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||||
[ValidateModelState]
|
[ValidateModelState]
|
||||||
[SwaggerOperation("CreateCurrency")]
|
[SwaggerOperation("CreateCurrency")]
|
||||||
|
[ProducesResponseType(201)]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<string>), 400)]
|
||||||
|
[ProducesResponseType(401)]
|
||||||
|
[ProducesResponseType(422)]
|
||||||
public virtual async Task<IActionResult> CreateCurrency([FromBody]CurrencyCreateBody body)
|
public virtual async Task<IActionResult> CreateCurrency([FromBody]CurrencyCreateBody body)
|
||||||
{
|
{
|
||||||
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||||
@ -129,6 +133,10 @@ namespace IO.Swagger.Controllers
|
|||||||
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||||
[ValidateModelState]
|
[ValidateModelState]
|
||||||
[SwaggerOperation("MintCurrency")]
|
[SwaggerOperation("MintCurrency")]
|
||||||
|
[ProducesResponseType(200)]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<string>), 400)]
|
||||||
|
[ProducesResponseType(401)]
|
||||||
|
[ProducesResponseType(409)]
|
||||||
public virtual async Task<IActionResult> MintCurrency([FromBody]CurrencyMintBody body)
|
public virtual async Task<IActionResult> MintCurrency([FromBody]CurrencyMintBody body)
|
||||||
{
|
{
|
||||||
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||||
|
|||||||
@ -18,6 +18,11 @@ using IO.Swagger.Attributes;
|
|||||||
using IO.Swagger.Security;
|
using IO.Swagger.Security;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using IO.Swagger.Models.dto;
|
using IO.Swagger.Models.dto;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using IO.Swagger.Repositories;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
namespace IO.Swagger.Controllers
|
namespace IO.Swagger.Controllers
|
||||||
{
|
{
|
||||||
@ -26,26 +31,67 @@ namespace IO.Swagger.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class WalletApiController : ControllerBase
|
public class WalletApiController : ControllerBase
|
||||||
{
|
{
|
||||||
|
private readonly ITransactionRepository transactionRepository;
|
||||||
|
private readonly IMapper mapper;
|
||||||
|
|
||||||
|
public WalletApiController(ITransactionRepository transactionRepository, IMapper mapper)
|
||||||
|
{
|
||||||
|
this.transactionRepository = transactionRepository ?? throw new ArgumentNullException(nameof(transactionRepository));
|
||||||
|
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get user's wallet
|
/// Get user's wallet balances
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <response code="200">Successful response</response>
|
/// <response code="200">Successful response</response>
|
||||||
/// <response code="401">Unauthorized</response>
|
/// <response code="401">Unauthorized</response>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("/v1/api/wallet")]
|
[Route("/v1/api/wallet/balances")]
|
||||||
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||||
[ValidateModelState]
|
[ValidateModelState]
|
||||||
[SwaggerOperation("GetUserWallet")]
|
[SwaggerOperation("GetUserBalances")]
|
||||||
public virtual IActionResult GetUserWallet()
|
[ProducesResponseType(typeof(WalletBalanceDto), 200)]
|
||||||
{
|
[ProducesResponseType(401)]
|
||||||
//TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
public virtual async Task<IActionResult> GetUserBalances()
|
||||||
// return StatusCode(200);
|
{
|
||||||
|
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||||
|
if (!int.TryParse(userIdString, out int userId))
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
//TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
var transactions = await transactionRepository.GetTransactionsForUser(userId);
|
||||||
// return StatusCode(401);
|
var balances = transactions.GroupBy(t => t.Currency)
|
||||||
|
.Select(g => new WalletBalanceDto
|
||||||
|
{
|
||||||
|
Currency = mapper.Map<CurrencyDto>(g.Key),
|
||||||
|
Balance = g.Sum(t =>t.Amount)
|
||||||
|
});
|
||||||
|
return Ok(balances);
|
||||||
|
}
|
||||||
|
|
||||||
throw new NotImplementedException();
|
/// <summary>
|
||||||
|
/// Get user's wallet transactions
|
||||||
|
/// </summary>
|
||||||
|
/// <response code="200">Successful response</response>
|
||||||
|
/// <response code="401">Unauthorized</response>
|
||||||
|
[HttpGet]
|
||||||
|
[Route("/v1/api/wallet/transactions")]
|
||||||
|
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||||
|
[ValidateModelState]
|
||||||
|
[SwaggerOperation("GetUserTransactions")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<TransactionDto>), 200)]
|
||||||
|
[ProducesResponseType(401)]
|
||||||
|
public virtual async Task<IActionResult> GetUserTransactions()
|
||||||
|
{
|
||||||
|
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||||
|
if (!int.TryParse(userIdString, out int userId))
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
var transactions = await transactionRepository.GetTransactionsForUser(userId);
|
||||||
|
|
||||||
|
return Ok(transactions.Select(mapper.Map<TransactionDto>));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
<PackageId>IO.Swagger</PackageId>
|
<PackageId>IO.Swagger</PackageId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.10" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.10" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10">
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace IO.Swagger.Models.db
|
namespace IO.Swagger.Models.db
|
||||||
{
|
{
|
||||||
@ -17,7 +18,6 @@ namespace IO.Swagger.Models.db
|
|||||||
[ForeignKey("FK_Currency_UserId")]
|
[ForeignKey("FK_Currency_UserId")]
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
public User User { get; set; }
|
public User User { get; set; }
|
||||||
|
|
||||||
public ICollection<Transaction> Transactions { get; set; }
|
public ICollection<Transaction> Transactions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using Microsoft.VisualBasic;
|
using Microsoft.VisualBasic;
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace IO.Swagger.Models.db
|
namespace IO.Swagger.Models.db
|
||||||
{
|
{
|
||||||
@ -19,7 +20,7 @@ namespace IO.Swagger.Models.db
|
|||||||
[Required]
|
[Required]
|
||||||
[StringLength(32, MinimumLength = 2)]
|
[StringLength(32, MinimumLength = 2)]
|
||||||
public string Memo { get; set; }
|
public string Memo { get; set; }
|
||||||
|
|
||||||
public Currency Currency { get; set; }
|
public Currency Currency { get; set; }
|
||||||
public int CurrencyId { get; set; }
|
public int CurrencyId { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace IO.Swagger.Models.db
|
namespace IO.Swagger.Models.db
|
||||||
{
|
{
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
[StringLength(32, MinimumLength = 3)]
|
[StringLength(32, MinimumLength = 3)]
|
||||||
public string FirstName { get; set; }
|
public string FirstName { get; set; }
|
||||||
@ -14,9 +16,7 @@ namespace IO.Swagger.Models.db
|
|||||||
public string LastName { get; set; }
|
public string LastName { get; set; }
|
||||||
public string PasswordHash { get; set; }
|
public string PasswordHash { get; set; }
|
||||||
public string Salt { get; set; }
|
public string Salt { get; set; }
|
||||||
|
|
||||||
public ICollection<Currency> Currencies { get; set; }
|
public ICollection<Currency> Currencies { get; set; }
|
||||||
|
|
||||||
public ICollection<Transaction> TransactionsFrom { get; set; }
|
public ICollection<Transaction> TransactionsFrom { get; set; }
|
||||||
public ICollection<Transaction> TransactionsTo { get; set; }
|
public ICollection<Transaction> TransactionsTo { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/IO.Swagger/Models/dto/CurrencyDto.cs
Normal file
13
src/IO.Swagger/Models/dto/CurrencyDto.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace IO.Swagger.Models.dto
|
||||||
|
{
|
||||||
|
public class CurrencyDto
|
||||||
|
{
|
||||||
|
public int CurrencyId { get; set; }
|
||||||
|
[StringLength(32, MinimumLength = 1)]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[StringLength(4, MinimumLength = 1)]
|
||||||
|
public string Symbol { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/IO.Swagger/Models/dto/TokenDto.cs
Normal file
7
src/IO.Swagger/Models/dto/TokenDto.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace IO.Swagger.Models.dto
|
||||||
|
{
|
||||||
|
public class TokenDto
|
||||||
|
{
|
||||||
|
public string Token { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/IO.Swagger/Models/dto/TransactionDto.cs
Normal file
16
src/IO.Swagger/Models/dto/TransactionDto.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.SqlServer.Server;
|
||||||
|
using Microsoft.VisualBasic;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace IO.Swagger.Models.dto
|
||||||
|
{
|
||||||
|
public class TransactionDto
|
||||||
|
{
|
||||||
|
public UserDto FromUser { get; set; }
|
||||||
|
public UserDto ToUser { get; set; }
|
||||||
|
public float Amount { get; set; }
|
||||||
|
public CurrencyDto Currency { get; set; }
|
||||||
|
public string Memo { get; set; }
|
||||||
|
public DateTime TransactionTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/IO.Swagger/Models/dto/UserDto.cs
Normal file
13
src/IO.Swagger/Models/dto/UserDto.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using IO.Swagger.Models.db;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace IO.Swagger.Models.dto
|
||||||
|
{
|
||||||
|
public class UserDto
|
||||||
|
{
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
public string LastName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/IO.Swagger/Models/dto/WalletBalanceDto.cs
Normal file
8
src/IO.Swagger/Models/dto/WalletBalanceDto.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace IO.Swagger.Models.dto
|
||||||
|
{
|
||||||
|
public class WalletBalanceDto
|
||||||
|
{
|
||||||
|
public CurrencyDto Currency { get; set; }
|
||||||
|
public float Balance { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/IO.Swagger/Repositories/ITransactionRepository.cs
Normal file
11
src/IO.Swagger/Repositories/ITransactionRepository.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using IO.Swagger.Models.db;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IO.Swagger.Repositories
|
||||||
|
{
|
||||||
|
public interface ITransactionRepository
|
||||||
|
{
|
||||||
|
Task<List<Transaction>> GetTransactionsForUser(int userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/IO.Swagger/Repositories/TransactionRepository.cs
Normal file
35
src/IO.Swagger/Repositories/TransactionRepository.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using IO.Swagger.Models.db;
|
||||||
|
using IO.Swagger.Services;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace IO.Swagger.Repositories
|
||||||
|
{
|
||||||
|
public class TransactionRepository : ITransactionRepository
|
||||||
|
{
|
||||||
|
BankDbContext context;
|
||||||
|
|
||||||
|
public TransactionRepository(BankDbContext context)
|
||||||
|
{
|
||||||
|
this.context = context ?? throw new ArgumentNullException(nameof(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Transaction>> GetTransactionsForUser(int userId)
|
||||||
|
{
|
||||||
|
var transactions = await context.Transactions.Where(t => t.ToUserId == userId || t.FromUserId == userId)
|
||||||
|
.Include(t => t.Currency)
|
||||||
|
.Include(t => t.FromUser)
|
||||||
|
.Include(t => t.ToUser)
|
||||||
|
.OrderByDescending(t => t.TransactionTime)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var t in transactions)
|
||||||
|
if (t.ToUserId != t.FromUserId && t.FromUserId == userId)
|
||||||
|
t.Amount *= -1;
|
||||||
|
return transactions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/IO.Swagger/Services/MapperProfile.cs
Normal file
16
src/IO.Swagger/Services/MapperProfile.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using IO.Swagger.Models.db;
|
||||||
|
using IO.Swagger.Models.dto;
|
||||||
|
|
||||||
|
namespace IO.Swagger.Services
|
||||||
|
{
|
||||||
|
public class MapperProfile : Profile
|
||||||
|
{
|
||||||
|
public MapperProfile()
|
||||||
|
{
|
||||||
|
CreateMap<User, UserDto>();
|
||||||
|
CreateMap<Currency, CurrencyDto>();
|
||||||
|
CreateMap<Transaction, TransactionDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,6 +26,7 @@ using IO.Swagger.Security;
|
|||||||
using IO.Swagger.Repositories;
|
using IO.Swagger.Repositories;
|
||||||
using IO.Swagger.Services;
|
using IO.Swagger.Services;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
namespace IO.Swagger
|
namespace IO.Swagger
|
||||||
{
|
{
|
||||||
@ -122,6 +123,14 @@ namespace IO.Swagger
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Auto Mapper Configurations
|
||||||
|
var mapperConfig = new MapperConfiguration(mc =>
|
||||||
|
{
|
||||||
|
mc.AddProfile(new MapperProfile());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// CORS sucks
|
||||||
services.AddCors(opt => {
|
services.AddCors(opt => {
|
||||||
opt.AddDefaultPolicy(po =>
|
opt.AddDefaultPolicy(po =>
|
||||||
{
|
{
|
||||||
@ -132,17 +141,22 @@ namespace IO.Swagger
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Datase connections
|
||||||
string connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION_STRING");
|
string connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION_STRING");
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(connectionString))
|
if (string.IsNullOrEmpty(connectionString))
|
||||||
{
|
{
|
||||||
throw new Exception("Database connection string not found in environment variable.");
|
throw new Exception("Database connection string not found in environment variable.");
|
||||||
}
|
}
|
||||||
Console.WriteLine(connectionString);
|
|
||||||
|
// DI setup
|
||||||
services.AddScoped<IUserRepository, UserRepository>();
|
services.AddScoped<IUserRepository, UserRepository>();
|
||||||
services.AddScoped<ICurrencyRepository, CurrencyRepository>();
|
services.AddScoped<ICurrencyRepository, CurrencyRepository>();
|
||||||
|
services.AddScoped<ITransactionRepository, TransactionRepository>();
|
||||||
services.AddDbContext<BankDbContext>(x => x.UseSqlServer(connectionString: connectionString));
|
services.AddDbContext<BankDbContext>(x => x.UseSqlServer(connectionString: connectionString));
|
||||||
services.AddSingleton<JwtService>();
|
services.AddSingleton<JwtService>();
|
||||||
|
IMapper mapper = mapperConfig.CreateMapper();
|
||||||
|
services.AddSingleton(mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user