Compare commits
3 Commits
b81d0cf0bd
...
692e0ef96a
Author | SHA1 | Date | |
---|---|---|---|
692e0ef96a | |||
6f4fb29ae8 | |||
dee572f013 |
@ -9,6 +9,7 @@ using AAIntegration.SimmonsBank.API.Config;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AAIntegration.SimmonsBank.API.Entities;
|
using AAIntegration.SimmonsBank.API.Entities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@ -16,17 +17,23 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
public class AccountsController : ControllerBase
|
public class AccountsController : ControllerBase
|
||||||
{
|
{
|
||||||
private IAccountService _accountService;
|
private IAccountService _accountService;
|
||||||
|
private IUserService _userService;
|
||||||
private IMapper _mapper;
|
private IMapper _mapper;
|
||||||
private readonly AppSettings _appSettings;
|
private readonly AppSettings _appSettings;
|
||||||
|
private readonly ILogger<AccountsController> _logger;
|
||||||
|
|
||||||
public AccountsController(
|
public AccountsController(
|
||||||
IAccountService accountService,
|
IAccountService accountService,
|
||||||
|
IUserService userService,
|
||||||
IMapper mapper,
|
IMapper mapper,
|
||||||
IOptions<AppSettings> appSettings)
|
IOptions<AppSettings> appSettings,
|
||||||
|
ILogger<AccountsController> logger)
|
||||||
{
|
{
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
|
_userService = userService;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
_appSettings = appSettings.Value;
|
_appSettings = appSettings.Value;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@ -34,7 +41,7 @@ public class AccountsController : ControllerBase
|
|||||||
{
|
{
|
||||||
List<AccountDTO> accountDtos = new List<AccountDTO>();
|
List<AccountDTO> accountDtos = new List<AccountDTO>();
|
||||||
|
|
||||||
foreach (Account acc in _accountService.GetAll())
|
foreach (Account acc in _accountService.GetAll(GetCurrentUserId()))
|
||||||
accountDtos.Add(_mapper.Map<Account, AccountDTO>(acc));
|
accountDtos.Add(_mapper.Map<Account, AccountDTO>(acc));
|
||||||
|
|
||||||
return Ok(accountDtos);
|
return Ok(accountDtos);
|
||||||
@ -43,28 +50,42 @@ public class AccountsController : ControllerBase
|
|||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public IActionResult GetById(int id)
|
public IActionResult GetById(int id)
|
||||||
{
|
{
|
||||||
Account account = _accountService.GetById(id);
|
Account account = _accountService.GetById(id, GetCurrentUserId());
|
||||||
return Ok(_mapper.Map<Account, AccountDTO>(account));
|
return Ok(_mapper.Map<Account, AccountDTO>(account));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Create([FromBody]AccountCreateRequest model)
|
public IActionResult Create([FromBody]AccountCreateRequest model)
|
||||||
{
|
{
|
||||||
_accountService.Create(model);
|
_accountService.Create(model, GetCurrentUserId());
|
||||||
return Ok(new { message = "account created" });
|
return Ok(new { message = "account created" });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
public IActionResult Update(int id, [FromBody]AccountUpdateRequest model)
|
public IActionResult Update(int id, [FromBody]AccountUpdateRequest model)
|
||||||
{
|
{
|
||||||
_accountService.Update(id, model);
|
_accountService.Update(id, model, GetCurrentUserId());
|
||||||
return Ok(new { message = "account updated" });
|
return Ok(new { message = "account updated" });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public IActionResult Delete(int id)
|
public IActionResult Delete(int id)
|
||||||
{
|
{
|
||||||
_accountService.Delete(id);
|
_accountService.Delete(id, GetCurrentUserId());
|
||||||
return Ok(new { message = "account deleted" });
|
return Ok(new { message = "account deleted" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
private int GetCurrentUserId()
|
||||||
|
{
|
||||||
|
string apiKey = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||||
|
|
||||||
|
if (apiKey is null)
|
||||||
|
_logger.LogInformation($"ApiKey: is null");
|
||||||
|
|
||||||
|
_logger.LogInformation($"apiKey: {apiKey}");
|
||||||
|
|
||||||
|
return _userService.GetUser(apiKey).Id;
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,6 +10,7 @@ using System.Runtime.InteropServices;
|
|||||||
using AAIntegration.SimmonsBank.API.Entities;
|
using AAIntegration.SimmonsBank.API.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@ -17,17 +18,23 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
public class TransactionsController : ControllerBase
|
public class TransactionsController : ControllerBase
|
||||||
{
|
{
|
||||||
private ITransactionService _transactionService;
|
private ITransactionService _transactionService;
|
||||||
|
private IUserService _userService;
|
||||||
private IMapper _mapper;
|
private IMapper _mapper;
|
||||||
private readonly AppSettings _appSettings;
|
private readonly AppSettings _appSettings;
|
||||||
|
private readonly ILogger<TransactionsController> _logger;
|
||||||
|
|
||||||
public TransactionsController(
|
public TransactionsController(
|
||||||
ITransactionService transactionService,
|
ITransactionService transactionService,
|
||||||
|
IUserService userService,
|
||||||
IMapper mapper,
|
IMapper mapper,
|
||||||
IOptions<AppSettings> appSettings)
|
IOptions<AppSettings> appSettings,
|
||||||
|
ILogger<TransactionsController> logger)
|
||||||
{
|
{
|
||||||
_transactionService = transactionService;
|
_transactionService = transactionService;
|
||||||
|
_userService = userService;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
_appSettings = appSettings.Value;
|
_appSettings = appSettings.Value;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@ -35,7 +42,7 @@ public class TransactionsController : ControllerBase
|
|||||||
{
|
{
|
||||||
List<TransactionDto> transactionDtos = new List<TransactionDto>();
|
List<TransactionDto> transactionDtos = new List<TransactionDto>();
|
||||||
|
|
||||||
foreach (Transaction tran in _transactionService.GetAll())
|
foreach (Transaction tran in _transactionService.GetAll(this.GetCurrentUserId()))
|
||||||
{
|
{
|
||||||
if (accountId.HasValue
|
if (accountId.HasValue
|
||||||
&& (tran.DebitAccount == null || tran.DebitAccount.Id != accountId)
|
&& (tran.DebitAccount == null || tran.DebitAccount.Id != accountId)
|
||||||
@ -54,35 +61,49 @@ public class TransactionsController : ControllerBase
|
|||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public IActionResult GetById(int id)
|
public IActionResult GetById(int id)
|
||||||
{
|
{
|
||||||
Transaction tran = _transactionService.GetById(id);
|
Transaction tran = _transactionService.GetById(id, this.GetCurrentUserId());
|
||||||
return Ok(_mapper.Map<Transaction, TransactionDto>(tran));
|
return Ok(_mapper.Map<Transaction, TransactionDto>(tran));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("BulkAdd")]
|
[HttpPost("BulkAdd")]
|
||||||
public IActionResult BulkCreate([FromBody]List<TransactionCreate> model)
|
public IActionResult BulkCreate([FromBody]List<TransactionCreate> model)
|
||||||
{
|
{
|
||||||
List<Transaction> trans = _transactionService.BulkCreate(model).ToList();
|
List<Transaction> trans = _transactionService.BulkCreate(model, this.GetCurrentUserId()).ToList();
|
||||||
return Ok(new { message = $"{trans.Count()} transaction(s) created." });
|
return Ok(new { message = $"{trans.Count()} transaction(s) created." });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Create([FromBody]TransactionCreate model)
|
public IActionResult Create([FromBody]TransactionCreate model)
|
||||||
{
|
{
|
||||||
Transaction tran = _transactionService.Create(model);
|
Transaction tran = _transactionService.Create(model, this.GetCurrentUserId());
|
||||||
return Ok(new { message = $"transaction '{tran.Description}' created with id '{tran.Id}'." });
|
return Ok(new { message = $"transaction '{tran.Description}' created with id '{tran.Id}'." });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
public IActionResult Update(int id, [FromBody]TransactionUpdateRequest model)
|
public IActionResult Update(int id, [FromBody]TransactionUpdateRequest model)
|
||||||
{
|
{
|
||||||
_transactionService.Update(id, model);
|
_transactionService.Update(id, model, this.GetCurrentUserId());
|
||||||
return Ok(new { message = $"transaction with id '{id}' updated" });
|
return Ok(new { message = $"transaction with id '{id}' updated" });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public IActionResult Delete(int id)
|
public IActionResult Delete(int id)
|
||||||
{
|
{
|
||||||
_transactionService.Delete(id);
|
_transactionService.Delete(id, this.GetCurrentUserId());
|
||||||
return Ok(new { message = "transaction deleted" });
|
return Ok(new { message = "transaction deleted" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
private int GetCurrentUserId()
|
||||||
|
{
|
||||||
|
string apiKey = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||||
|
|
||||||
|
if (apiKey is null)
|
||||||
|
_logger.LogInformation($"ApiKey: is null");
|
||||||
|
|
||||||
|
_logger.LogInformation($"apiKey: {apiKey}");
|
||||||
|
|
||||||
|
return _userService.GetUser(apiKey).Id;
|
||||||
|
}
|
||||||
}
|
}
|
@ -39,7 +39,7 @@ public class UsersController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[HttpPut("{id}")]
|
[HttpPut]
|
||||||
public IActionResult Update([FromBody]UserUpdateRequest model)
|
public IActionResult Update([FromBody]UserUpdateRequest model)
|
||||||
{
|
{
|
||||||
_userService.Update(this.GetCurrentUserApiKey(), model);
|
_userService.Update(this.GetCurrentUserApiKey(), model);
|
||||||
@ -47,8 +47,8 @@ public class UsersController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete]
|
||||||
public IActionResult Delete(int id)
|
public IActionResult Delete()
|
||||||
{
|
{
|
||||||
_userService.Delete(this.GetCurrentUserApiKey());
|
_userService.Delete(this.GetCurrentUserApiKey());
|
||||||
return Ok(new { message = "User deleted" });
|
return Ok(new { message = "User deleted" });
|
||||||
@ -64,7 +64,6 @@ public class UsersController : ControllerBase
|
|||||||
_logger.LogInformation($"ApiKey: is null");
|
_logger.LogInformation($"ApiKey: is null");
|
||||||
|
|
||||||
_logger.LogInformation($"apiKey: {apiKey}");
|
_logger.LogInformation($"apiKey: {apiKey}");
|
||||||
Console.WriteLine($"User Id: " + apiKey);
|
|
||||||
|
|
||||||
return apiKey;
|
return apiKey;
|
||||||
}
|
}
|
||||||
|
@ -8,4 +8,5 @@ public class Account
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public decimal Balance { get; set; }
|
public decimal Balance { get; set; }
|
||||||
public string ExternalAccountNumber { get; set; }
|
public string ExternalAccountNumber { get; set; }
|
||||||
|
public User Owner { get; set; }
|
||||||
}
|
}
|
@ -15,4 +15,5 @@ public class Transaction
|
|||||||
public Account? CreditAccount { get; set; }
|
public Account? CreditAccount { get; set; }
|
||||||
public decimal Amount { get; set; }
|
public decimal Amount { get; set; }
|
||||||
public bool IsPending { get; set; }
|
public bool IsPending { get; set; }
|
||||||
|
public User Owner { get; set; }
|
||||||
}
|
}
|
173
AAIntegration.SimmonsBank.API/Migrations/20240320022712_UserOwnedEntities.Designer.cs
generated
Normal file
173
AAIntegration.SimmonsBank.API/Migrations/20240320022712_UserOwnedEntities.Designer.cs
generated
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AAIntegration.SimmonsBank.API.Config;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AAIntegration.SimmonsBank.API.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DataContext))]
|
||||||
|
[Migration("20240320022712_UserOwnedEntities")]
|
||||||
|
partial class UserOwnedEntities
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "7.0.9")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<decimal>("Balance")
|
||||||
|
.HasColumnType("numeric");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalAccountNumber")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("OwnerId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.ToTable("Accounts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<decimal>("Amount")
|
||||||
|
.HasColumnType("numeric");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int?>("CreditAccountId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int?>("DebitAccountId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPending")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<int>("OwnerId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreditAccountId");
|
||||||
|
|
||||||
|
b.HasIndex("DebitAccountId");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.ToTable("Transactions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ApiKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("MFAKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("SimmonsBankPassword")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("SimmonsBankUsername")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CreditAccountId");
|
||||||
|
|
||||||
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("DebitAccountId");
|
||||||
|
|
||||||
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("CreditAccount");
|
||||||
|
|
||||||
|
b.Navigation("DebitAccount");
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AAIntegration.SimmonsBank.API.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class UserOwnedEntities : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "OwnerId",
|
||||||
|
table: "Transactions",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "OwnerId",
|
||||||
|
table: "Accounts",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Transactions_OwnerId",
|
||||||
|
table: "Transactions",
|
||||||
|
column: "OwnerId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Accounts_OwnerId",
|
||||||
|
table: "Accounts",
|
||||||
|
column: "OwnerId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Accounts_Users_OwnerId",
|
||||||
|
table: "Accounts",
|
||||||
|
column: "OwnerId",
|
||||||
|
principalTable: "Users",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Transactions_Users_OwnerId",
|
||||||
|
table: "Transactions",
|
||||||
|
column: "OwnerId",
|
||||||
|
principalTable: "Users",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Accounts_Users_OwnerId",
|
||||||
|
table: "Accounts");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Transactions_Users_OwnerId",
|
||||||
|
table: "Transactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Transactions_OwnerId",
|
||||||
|
table: "Transactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Accounts_OwnerId",
|
||||||
|
table: "Accounts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "OwnerId",
|
||||||
|
table: "Transactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "OwnerId",
|
||||||
|
table: "Accounts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -41,8 +41,13 @@ namespace AAIntegration.SimmonsBank.API.Migrations
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("OwnerId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
b.ToTable("Accounts");
|
b.ToTable("Accounts");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -80,6 +85,9 @@ namespace AAIntegration.SimmonsBank.API.Migrations
|
|||||||
b.Property<bool>("IsPending")
|
b.Property<bool>("IsPending")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<int>("OwnerId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<DateTime>("UpdatedOn")
|
b.Property<DateTime>("UpdatedOn")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
@ -89,6 +97,8 @@ namespace AAIntegration.SimmonsBank.API.Migrations
|
|||||||
|
|
||||||
b.HasIndex("DebitAccountId");
|
b.HasIndex("DebitAccountId");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
b.ToTable("Transactions");
|
b.ToTable("Transactions");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -121,6 +131,17 @@ namespace AAIntegration.SimmonsBank.API.Migrations
|
|||||||
b.ToTable("Users");
|
b.ToTable("Users");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
|
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
|
||||||
@ -131,9 +152,17 @@ namespace AAIntegration.SimmonsBank.API.Migrations
|
|||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("DebitAccountId");
|
.HasForeignKey("DebitAccountId");
|
||||||
|
|
||||||
|
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("CreditAccount");
|
b.Navigation("CreditAccount");
|
||||||
|
|
||||||
b.Navigation("DebitAccount");
|
b.Navigation("DebitAccount");
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
});
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,5 @@ public class AccountCreateRequest
|
|||||||
public string InitialBalance { get; set; }
|
public string InitialBalance { get; set; }
|
||||||
public int Currency { get; set; }
|
public int Currency { get; set; }
|
||||||
public string ExternalAccountNumber { get; set; }
|
public string ExternalAccountNumber { get; set; }
|
||||||
|
public int Owner { get; set; }
|
||||||
}
|
}
|
@ -14,11 +14,11 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
public interface IAccountService
|
public interface IAccountService
|
||||||
{
|
{
|
||||||
IEnumerable<Account> GetAll();
|
IEnumerable<Account> GetAll(int ownerId);
|
||||||
Account GetById(int accountId);
|
Account GetById(int accountId, int ownerId);
|
||||||
void Create(AccountCreateRequest model);
|
void Create(AccountCreateRequest model, int ownerId);
|
||||||
void Update(int accountId, AccountUpdateRequest model);
|
void Update(int accountId, AccountUpdateRequest model, int ownerId);
|
||||||
void Delete(int accountId);
|
void Delete(int accountId, int ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AccountService : IAccountService
|
public class AccountService : IAccountService
|
||||||
@ -37,51 +37,57 @@ public class AccountService : IAccountService
|
|||||||
_userService = userService;
|
_userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Account> GetAll()
|
public IEnumerable<Account> GetAll(int ownerId)
|
||||||
{
|
{
|
||||||
return _context.Accounts;
|
return _context.Accounts
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Where(x => x.Owner.Id == ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account GetById(int accountId)
|
public Account GetById(int accountId, int ownerId)
|
||||||
{
|
{
|
||||||
return getAccount(accountId);
|
return getAccount(accountId, ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(AccountCreateRequest model)
|
public void Create(AccountCreateRequest model, int ownerId)
|
||||||
{
|
{
|
||||||
// Check that account with same name or same external number doesn't exist
|
// Check that account with same name or same external number doesn't exist
|
||||||
IEnumerable<Account> accountsWithSameName = _context.Accounts.Where(a => a.Name.ToUpper() == model.Name.ToUpper());
|
IEnumerable<Account> accountsWithSameName = _context.Accounts
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Where(x => x.Name.ToUpper() == model.Name.ToUpper() && x.Owner.Id == ownerId);
|
||||||
|
|
||||||
if (accountsWithSameName.Count() > 0)
|
if (accountsWithSameName.Count() > 0)
|
||||||
throw new AppException("Account with name '" + model.Name + "' already exists");
|
throw new AppException("Account with name '" + model.Name + "' already exists");
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber))
|
if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber))
|
||||||
{
|
{
|
||||||
IEnumerable<Account> matches = _context.Accounts.Where(a => a.ExternalAccountNumber == model.ExternalAccountNumber);
|
IEnumerable<Account> matches = _context.Accounts
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Where(x => x.ExternalAccountNumber == model.ExternalAccountNumber && x.Owner.Id == ownerId);
|
||||||
|
|
||||||
if (matches.Count() > 0)
|
if (matches.Count() > 0)
|
||||||
throw new AppException("Account with external account number '" + model.ExternalAccountNumber + "' already exists under account named '" + matches.First().Name + "'");
|
throw new AppException("Account with external account number '" + model.ExternalAccountNumber + "' already exists under account named '" + matches.First().Name + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// map model to new account object
|
|
||||||
//var account = _mapper.Map<Account>(model);
|
|
||||||
|
|
||||||
Account account = new Account {
|
Account account = new Account {
|
||||||
Name = model.Name,
|
Name = model.Name,
|
||||||
Balance = Convert.ToDecimal(model.InitialBalance),
|
Balance = Convert.ToDecimal(model.InitialBalance),
|
||||||
ExternalAccountNumber = model.ExternalAccountNumber
|
ExternalAccountNumber = model.ExternalAccountNumber,
|
||||||
|
Owner = getOwner(ownerId)
|
||||||
};
|
};
|
||||||
|
|
||||||
_context.Accounts.Add(account);
|
_context.Accounts.Add(account);
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(int accountId, AccountUpdateRequest model)
|
public void Update(int accountId, AccountUpdateRequest model, int ownerId)
|
||||||
{
|
{
|
||||||
Account account = getAccount(accountId);
|
Account account = getAccount(accountId, ownerId);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
if (model.Name != account.Name && _context.Accounts.Any(x => x.Name == model.Name))
|
if (model.Name != account.Name && _context.Accounts
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Any(x => x.Name == model.Name && x.Owner.Id == ownerId))
|
||||||
throw new AppException("Account with the name '" + model.Name + "' already exists");
|
throw new AppException("Account with the name '" + model.Name + "' already exists");
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
@ -96,19 +102,31 @@ public class AccountService : IAccountService
|
|||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int accountId)
|
public void Delete(int accountId, int ownerId)
|
||||||
{
|
{
|
||||||
var account = getAccount(accountId);
|
var account = getAccount(accountId, ownerId);
|
||||||
_context.Accounts.Remove(account);
|
_context.Accounts.Remove(account);
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper methods
|
// helper methods
|
||||||
|
|
||||||
private Account getAccount(int id)
|
private Account getAccount(int id, int ownerId)
|
||||||
{
|
{
|
||||||
var account = _context.Accounts.Find(id);
|
var account = _context.Accounts
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.FirstOrDefault(x => x.Id == id && x.Owner.Id == ownerId);
|
||||||
if (account == null) throw new KeyNotFoundException("Account not found");
|
if (account == null) throw new KeyNotFoundException("Account not found");
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private User getOwner(int ownerId)
|
||||||
|
{
|
||||||
|
User? owner = _context.Users.Find(ownerId);
|
||||||
|
|
||||||
|
if (owner == null)
|
||||||
|
throw new AppException($"Owner with ID of '{ownerId}' could not be found");
|
||||||
|
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,30 +11,49 @@ public class CacheService : ICacheService
|
|||||||
{
|
{
|
||||||
private readonly IMemoryCache _memoryCache;
|
private readonly IMemoryCache _memoryCache;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
|
private readonly ILogger<ICacheService> _logger;
|
||||||
|
|
||||||
public CacheService(IMemoryCache memoryCache, IUserService userService)
|
public CacheService(IMemoryCache memoryCache, IUserService userService, ILogger<ICacheService> logger)
|
||||||
{
|
{
|
||||||
_memoryCache = memoryCache;
|
_memoryCache = memoryCache;
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetClientIdFromApiKey(string apiKey)
|
public int GetClientIdFromApiKey(string apiKey)
|
||||||
{
|
{
|
||||||
if (!_memoryCache.TryGetValue<Dictionary<string, int>>($"Authentication_ApiKeys", out var internalKeys))
|
if (!_memoryCache.TryGetValue<Dictionary<string, int>>($"Authentication_ApiKeys", out var internalKeys))
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation($"Could not find API key '{apiKey}' in cache.");
|
||||||
|
|
||||||
internalKeys = _userService.GetAllApiKeys();
|
internalKeys = _userService.GetAllApiKeys();
|
||||||
|
|
||||||
|
_logger.LogInformation("Updated cache with new key list.");
|
||||||
|
PrintInternalKeys(internalKeys);
|
||||||
|
|
||||||
_memoryCache.Set($"Authentication_ApiKeys", internalKeys);
|
_memoryCache.Set($"Authentication_ApiKeys", internalKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!internalKeys.TryGetValue(apiKey, out var clientId))
|
if (!internalKeys.TryGetValue(apiKey, out var clientId))
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation("Could not find API key. Returning -1.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
|
||||||
|
private void PrintInternalKeys(Dictionary<string, int> keys)
|
||||||
|
{
|
||||||
|
string msg = "API Keys (dev only - needs to be moved to dev only)";
|
||||||
|
foreach (var item in keys)
|
||||||
|
msg += $"\n\t{item.Value} : {item.Key}";
|
||||||
|
|
||||||
|
_logger.LogInformation(msg);
|
||||||
|
}
|
||||||
|
|
||||||
/*public void InvalidateApiKey(string apiKey)
|
/*public void InvalidateApiKey(string apiKey)
|
||||||
{
|
{
|
||||||
if (_memoryCache.TryGetValue<Dictionary<string, Guid>>("Authentication_ApiKeys", out var internalKeys))
|
if (_memoryCache.TryGetValue<Dictionary<string, Guid>>("Authentication_ApiKeys", out var internalKeys))
|
||||||
|
@ -15,12 +15,12 @@ using System.Collections.Immutable;
|
|||||||
|
|
||||||
public interface ITransactionService
|
public interface ITransactionService
|
||||||
{
|
{
|
||||||
IEnumerable<Transaction> GetAll();
|
IEnumerable<Transaction> GetAll(int ownerId);
|
||||||
Transaction GetById(int id);
|
Transaction GetById(int id, int ownerId);
|
||||||
IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model);
|
IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model, int ownerId);
|
||||||
Transaction Create(TransactionCreate model, bool errorOnFail = true);
|
Transaction Create(TransactionCreate model, int ownerId, bool errorOnFail = true);
|
||||||
void Update(int id, TransactionUpdateRequest model);
|
void Update(int id, TransactionUpdateRequest model, int ownerId);
|
||||||
void Delete(int id);
|
void Delete(int id, int ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TransactionService : ITransactionService
|
public class TransactionService : ITransactionService
|
||||||
@ -39,17 +39,18 @@ public class TransactionService : ITransactionService
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Transaction> GetAll()
|
public IEnumerable<Transaction> GetAll(int ownerId)
|
||||||
{
|
{
|
||||||
return _context.Transactions
|
return _context.Transactions
|
||||||
.Include(t => t.DebitAccount)
|
.Include(t => t.DebitAccount)
|
||||||
.Include(t => t.CreditAccount)
|
.Include(t => t.CreditAccount)
|
||||||
.ToList();
|
.Include(t => t.Owner)
|
||||||
|
.Where(x => x.Owner.Id == ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transaction GetById(int id)
|
public Transaction GetById(int id, int ownerId)
|
||||||
{
|
{
|
||||||
return getTransaction(id);
|
return getTransaction(id, ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Account prepareAccount(int? accountId)
|
private Account prepareAccount(int? accountId)
|
||||||
@ -66,13 +67,13 @@ public class TransactionService : ITransactionService
|
|||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model)
|
public IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model, int ownerId)
|
||||||
{
|
{
|
||||||
List<Transaction> transactions = new List<Transaction>();
|
List<Transaction> transactions = new List<Transaction>();
|
||||||
|
|
||||||
foreach (TransactionCreate tr in model)
|
foreach (TransactionCreate tr in model)
|
||||||
{
|
{
|
||||||
var tran = this.Create(tr, false);
|
var tran = this.Create(tr, ownerId, false);
|
||||||
if (tran != null)
|
if (tran != null)
|
||||||
transactions.Add(tran);
|
transactions.Add(tran);
|
||||||
}
|
}
|
||||||
@ -80,7 +81,7 @@ public class TransactionService : ITransactionService
|
|||||||
return transactions;
|
return transactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transaction Create(TransactionCreate model, bool errorOnFail = true)
|
public Transaction Create(TransactionCreate model, int ownerId, bool errorOnFail = true)
|
||||||
{
|
{
|
||||||
Transaction transaction = new Transaction {
|
Transaction transaction = new Transaction {
|
||||||
Description = model.Description,
|
Description = model.Description,
|
||||||
@ -91,10 +92,11 @@ public class TransactionService : ITransactionService
|
|||||||
DebitAccount = prepareAccount(model.DebitAccount),
|
DebitAccount = prepareAccount(model.DebitAccount),
|
||||||
CreditAccount = prepareAccount(model.CreditAccount),
|
CreditAccount = prepareAccount(model.CreditAccount),
|
||||||
Amount = Convert.ToDecimal(model.Amount),
|
Amount = Convert.ToDecimal(model.Amount),
|
||||||
|
Owner = this.getOwner(ownerId),
|
||||||
IsPending = model.IsPending
|
IsPending = model.IsPending
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.ValidateTransaction(transaction, errorOnFail) == false)
|
if (this.ValidateTransaction(transaction, ownerId, errorOnFail) == false)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Aborted adding transaction '{transaction.Description}'.");
|
_logger.LogInformation($"Aborted adding transaction '{transaction.Description}'.");
|
||||||
return null;
|
return null;
|
||||||
@ -110,9 +112,9 @@ public class TransactionService : ITransactionService
|
|||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(int id, TransactionUpdateRequest model)
|
public void Update(int id, TransactionUpdateRequest model, int ownerId)
|
||||||
{
|
{
|
||||||
Transaction transaction = getTransaction(id);
|
Transaction transaction = getTransaction(id, ownerId);
|
||||||
|
|
||||||
// Transaction.Date
|
// Transaction.Date
|
||||||
if (model.Date.HasValue)
|
if (model.Date.HasValue)
|
||||||
@ -142,7 +144,7 @@ public class TransactionService : ITransactionService
|
|||||||
if (model.IsPending.HasValue)
|
if (model.IsPending.HasValue)
|
||||||
transaction.IsPending = model.IsPending.Value;
|
transaction.IsPending = model.IsPending.Value;
|
||||||
|
|
||||||
this.ValidateTransaction(transaction);
|
this.ValidateTransaction(transaction, ownerId);
|
||||||
|
|
||||||
transaction.UpdatedOn = DateTime.UtcNow;
|
transaction.UpdatedOn = DateTime.UtcNow;
|
||||||
|
|
||||||
@ -152,11 +154,15 @@ public class TransactionService : ITransactionService
|
|||||||
_logger.LogInformation($"Transaction '{id}' successfully updated.");
|
_logger.LogInformation($"Transaction '{id}' successfully updated.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateTransaction(int transactionId)
|
public void Delete(int id, int ownerId)
|
||||||
{
|
{
|
||||||
return this.ValidateTransaction(getTransaction(transactionId));
|
var transaction = getTransaction(id, ownerId);
|
||||||
|
_context.Transactions.Remove(transaction);
|
||||||
|
_context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
|
||||||
private bool ErrorOrFalse(bool error, string errorMessage)
|
private bool ErrorOrFalse(bool error, string errorMessage)
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
@ -166,7 +172,7 @@ public class TransactionService : ITransactionService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateTransaction(Transaction transaction, bool errorOnFail = true)
|
private bool ValidateTransaction(Transaction transaction, int ownerId, bool errorOnFail = true)
|
||||||
{
|
{
|
||||||
// There has to be at least 1 specified account
|
// There has to be at least 1 specified account
|
||||||
if (transaction.DebitAccount == null && transaction.CreditAccount == null)
|
if (transaction.DebitAccount == null && transaction.CreditAccount == null)
|
||||||
@ -178,7 +184,10 @@ public class TransactionService : ITransactionService
|
|||||||
return ErrorOrFalse(errorOnFail, "The debit and credit accounts of a transaction cannot be the same.");
|
return ErrorOrFalse(errorOnFail, "The debit and credit accounts of a transaction cannot be the same.");
|
||||||
|
|
||||||
// Transaction Duplication Check - External ID
|
// Transaction Duplication Check - External ID
|
||||||
if (!string.IsNullOrWhiteSpace(transaction.ExternalId) && _context.Transactions.Any(x => x.ExternalId == transaction.ExternalId))
|
if (!string.IsNullOrWhiteSpace(transaction.ExternalId)
|
||||||
|
&& _context.Transactions
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Any(x => x.ExternalId == transaction.ExternalId && x.Owner.Id == ownerId))
|
||||||
return ErrorOrFalse(errorOnFail, "Transaction with the external ID '" + transaction.ExternalId + "' already exists");
|
return ErrorOrFalse(errorOnFail, "Transaction with the external ID '" + transaction.ExternalId + "' already exists");
|
||||||
|
|
||||||
// Transaction Duplication Check - All other fields
|
// Transaction Duplication Check - All other fields
|
||||||
@ -195,23 +204,27 @@ public class TransactionService : ITransactionService
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
private Transaction getTransaction(int id, int ownerId)
|
||||||
{
|
|
||||||
var transaction = getTransaction(id);
|
|
||||||
_context.Transactions.Remove(transaction);
|
|
||||||
_context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Transaction getTransaction(int id)
|
|
||||||
{
|
{
|
||||||
var transaction = _context.Transactions
|
var transaction = _context.Transactions
|
||||||
.Include(t => t.DebitAccount)
|
.Include(t => t.DebitAccount)
|
||||||
.Include(t => t.CreditAccount)
|
.Include(t => t.CreditAccount)
|
||||||
.FirstOrDefault(t => t.Id == id);
|
.Include(t => t.Owner)
|
||||||
|
.FirstOrDefault(t => t.Id == id && t.Owner.Id == ownerId);
|
||||||
|
|
||||||
if (transaction == null)
|
if (transaction == null)
|
||||||
throw new KeyNotFoundException("Transaction not found");
|
throw new KeyNotFoundException("Transaction not found");
|
||||||
|
|
||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private User getOwner(int ownerId)
|
||||||
|
{
|
||||||
|
User? owner = _context.Users.Find(ownerId);
|
||||||
|
|
||||||
|
if (owner == null)
|
||||||
|
throw new AppException($"Owner with ID of '{ownerId}' could not be found");
|
||||||
|
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
}
|
}
|
@ -23,6 +23,7 @@ public interface IUserService
|
|||||||
void Update(string apiKey, UserUpdateRequest model);
|
void Update(string apiKey, UserUpdateRequest model);
|
||||||
void Delete(string apiKey);
|
void Delete(string apiKey);
|
||||||
Dictionary<string, int> GetAllApiKeys();
|
Dictionary<string, int> GetAllApiKeys();
|
||||||
|
User GetUser(string ApiKey);
|
||||||
|
|
||||||
/* Other cringe way
|
/* Other cringe way
|
||||||
AuthenticateResponse Authenticate(AuthenticateRequest model);
|
AuthenticateResponse Authenticate(AuthenticateRequest model);
|
||||||
@ -74,7 +75,7 @@ public class UserService : IUserService
|
|||||||
|
|
||||||
public void Update(string apiKey, UserUpdateRequest model)
|
public void Update(string apiKey, UserUpdateRequest model)
|
||||||
{
|
{
|
||||||
var user = getUser(apiKey);
|
var user = this.GetUser(apiKey);
|
||||||
|
|
||||||
// User.Username
|
// User.Username
|
||||||
if (model.Username != null)
|
if (model.Username != null)
|
||||||
@ -94,7 +95,7 @@ public class UserService : IUserService
|
|||||||
|
|
||||||
public void Delete(string apiKey)
|
public void Delete(string apiKey)
|
||||||
{
|
{
|
||||||
var user = getUser(apiKey);
|
var user = this.GetUser(apiKey);
|
||||||
_context.Users.Remove(user);
|
_context.Users.Remove(user);
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
}
|
}
|
||||||
@ -106,23 +107,20 @@ public class UserService : IUserService
|
|||||||
.ToDictionary(u => u.ApiKey, u => u.Id);
|
.ToDictionary(u => u.ApiKey, u => u.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User GetUser(string ApiKey)
|
||||||
|
{
|
||||||
|
var user = _context.Users
|
||||||
|
.Where(u => u.ApiKey == ApiKey)
|
||||||
|
.FirstOrDefault() ?? throw new KeyNotFoundException("User not found");
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
// helper methods
|
// helper methods
|
||||||
|
|
||||||
private User getUser(int id)
|
private User getUser(int id)
|
||||||
{
|
{
|
||||||
var user = _context.Users.Find(id);
|
var user = _context.Users.Find(id) ?? throw new KeyNotFoundException("User not found");
|
||||||
if (user == null) throw new KeyNotFoundException("User not found");
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
private User getUser(string ApiKey)
|
|
||||||
{
|
|
||||||
var user = _context.Users
|
|
||||||
.Where(u => u.ApiKey == ApiKey)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (user == null) throw new KeyNotFoundException("User not found");
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user