Added endpoint to access SimmonsBank accounts for the current user

This commit is contained in:
William Lewis 2024-04-03 15:36:27 -05:00
parent 48958be669
commit f32b07b2b8
6 changed files with 31 additions and 13 deletions

View File

@ -7,6 +7,7 @@ public class PuppeteerConfig
public int TaskCheckIntervalMinutes { get; set; } public int TaskCheckIntervalMinutes { get; set; }
public string SimmonsBankBaseUrl { get; set; } public string SimmonsBankBaseUrl { get; set; }
public int BrowserOperationTimeoutSeconds { get; set; } public int BrowserOperationTimeoutSeconds { get; set; }
public bool Headless { get; set; }
} }
public class PuppeteerConfigConstants public class PuppeteerConfigConstants
@ -16,6 +17,7 @@ public class PuppeteerConfigConstants
public const string TaskCheckIntervalMinutes = "TaskCheckIntervalMinutes"; public const string TaskCheckIntervalMinutes = "TaskCheckIntervalMinutes";
public const string SimmonsBankBaseUrl = "SimmonsBankBaseUrl"; public const string SimmonsBankBaseUrl = "SimmonsBankBaseUrl";
public const string BrowserOperationTimeoutSeconds = "BrowserOperationTimeoutSeconds"; public const string BrowserOperationTimeoutSeconds = "BrowserOperationTimeoutSeconds";
public const string Headless = "Headless";
} }
public class PuppeteerConstants public class PuppeteerConstants

View File

@ -10,6 +10,8 @@ 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; using System.Security.Claims;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
[Authorize] [Authorize]
[ApiController] [ApiController]
@ -21,30 +23,36 @@ public class AccountsController : ControllerBase
private IMapper _mapper; private IMapper _mapper;
private readonly AppSettings _appSettings; private readonly AppSettings _appSettings;
private readonly ILogger<AccountsController> _logger; private readonly ILogger<AccountsController> _logger;
private IPuppeteerService _puppeteerService;
public AccountsController( public AccountsController(
IAccountService accountService, IAccountService accountService,
IUserService userService, IUserService userService,
IMapper mapper, IMapper mapper,
IOptions<AppSettings> appSettings, IOptions<AppSettings> appSettings,
ILogger<AccountsController> logger) ILogger<AccountsController> logger,
IPuppeteerService puppeteerService)
{ {
_accountService = accountService; _accountService = accountService;
_userService = userService; _userService = userService;
_mapper = mapper; _mapper = mapper;
_appSettings = appSettings.Value; _appSettings = appSettings.Value;
_logger = logger; _logger = logger;
_puppeteerService = puppeteerService;
} }
[HttpGet] [HttpGet]
public IActionResult GetAll() public async Task<IActionResult> GetAllAsync()
{ {
List<AccountDTO> accountDtos = new List<AccountDTO>(); List<AccountDTO> accounts = await _puppeteerService.GetAccounts(_userService.GetUser(User.FindFirstValue(ClaimTypes.NameIdentifier)));
return Ok(accounts);
/*List<AccountDTO> accountDtos = new List<AccountDTO>();
foreach (Account acc in _accountService.GetAll(GetCurrentUserId())) 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);*/
} }
[HttpGet("{id}")] [HttpGet("{id}")]

View File

@ -7,8 +7,9 @@ namespace AAIntegration.SimmonsBank.API.Models.Accounts;
public class AccountDTO public class AccountDTO
{ {
public int Id { get; set; } public string Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public decimal Balance { get; set; } public string Numbers { get; set; }
public string ExternalAccountNumber { get; set; } public decimal? Balance { get; set; }
public decimal? AvailableBalance { get; set; }
} }

View File

@ -23,12 +23,13 @@ using Newtonsoft.Json.Linq;
using NuGet.Protocol; using NuGet.Protocol;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NuGet.Protocol.Core.Types; using NuGet.Protocol.Core.Types;
using AAIntegration.SimmonsBank.API.Models.Accounts;
public interface IPuppeteerService public interface IPuppeteerService
{ {
Task<bool> Login(User user, CancellationToken cancellationToken); Task<bool> Login(User user, CancellationToken cancellationToken);
Task<bool> IsLoggedIn(User user, CancellationToken cancellationToken); Task<bool> IsLoggedIn(User user, CancellationToken cancellationToken);
Task<JToken> GetAccounts(User user, CancellationToken cancellationToken); Task<List<AccountDTO>> GetAccounts(User user);
} }
public class PuppeteerService : IPuppeteerService public class PuppeteerService : IPuppeteerService
@ -222,7 +223,7 @@ public class PuppeteerService : IPuppeteerService
} }
public async Task<JToken> GetAccounts(User user, CancellationToken cancellationToken) public async Task<List<AccountDTO>> GetAccounts(User user)
{ {
string prefix = $"Task::GetAccounts - {user.Id} - "; string prefix = $"Task::GetAccounts - {user.Id} - ";
@ -235,7 +236,7 @@ public class PuppeteerService : IPuppeteerService
} }
// Setup Page // Setup Page
IBrowser browser = await GetUserBrowserAsync(user, cancellationToken); IBrowser browser = await GetUserBrowserAsync(user, new CancellationToken());
await using IPage page = await browser.NewPageAsync(); await using IPage page = await browser.NewPageAsync();
await page.SetUserAgentAsync(USER_AGENT); await page.SetUserAgentAsync(USER_AGENT);
await page.SetViewportAsync(new ViewPortOptions { Width = 1200, Height = 720 }); await page.SetViewportAsync(new ViewPortOptions { Width = 1200, Height = 720 });
@ -245,11 +246,14 @@ public class PuppeteerService : IPuppeteerService
try try
{ {
IResponse response = await page.GoToAsync(url).WaitAsync(TimeSpan.FromSeconds(_config.BrowserOperationTimeoutSeconds), cancellationToken); IResponse response = await page.GoToAsync(url).WaitAsync(TimeSpan.FromSeconds(_config.BrowserOperationTimeoutSeconds));
_logger.LogInformation(prefix + $"Request response code '{response.Status}'. Url: '{url}'"); _logger.LogInformation(prefix + $"Request response code '{response.Status}'. Url: '{url}'");
if (response.Status == System.Net.HttpStatusCode.OK) if (response.Status == System.Net.HttpStatusCode.OK)
return await response.JsonAsync<JToken>(); {
JToken accounts = await response.JsonAsync<JToken>();
return accounts.SelectToken("accounts").ToObject<List<AccountDTO>>();
}
else else
_logger.LogError(prefix + $"Received unexpected status code '{response.Status}'"); _logger.LogError(prefix + $"Received unexpected status code '{response.Status}'");
} }
@ -280,7 +284,7 @@ public class PuppeteerService : IPuppeteerService
await browserFetcher.DownloadAsync().WaitAsync(TimeSpan.FromSeconds(_config.BrowserOperationTimeoutSeconds * 20), cancellationToken); await browserFetcher.DownloadAsync().WaitAsync(TimeSpan.FromSeconds(_config.BrowserOperationTimeoutSeconds * 20), cancellationToken);
var options = new LaunchOptions { var options = new LaunchOptions {
Headless = true, Headless = _config.Headless,
IgnoreHTTPSErrors = true, IgnoreHTTPSErrors = true,
}; };

View File

@ -26,6 +26,7 @@
"APIUrl": "https://localhost:7260" "APIUrl": "https://localhost:7260"
}, },
"Puppeteer": { "Puppeteer": {
"Headless": true,
"BrowserOperationTimeoutSeconds": 5, "BrowserOperationTimeoutSeconds": 5,
"TaskCheckIntervalMinutes": 1, "TaskCheckIntervalMinutes": 1,
"KeepAliveIntervalMinutes": 1, "KeepAliveIntervalMinutes": 1,

View File

@ -8,6 +8,8 @@ The type is Transaction Importer, specifically created for interfacing with Simm
[Otp.NET library](https://github.com/kspearrin/Otp.NET) [Otp.NET library](https://github.com/kspearrin/Otp.NET)
[JToken.SelectToken() quick reference](https://www.newtonsoft.com/json/help/html/SelectToken.htm)
## Dev Environment Setup ## Dev Environment Setup
On Archlinux install the following to use dotnet: ```sudo pacman -Sy dotnet-sdk dotnet-runtime aspnet-runtime```. On Archlinux install the following to use dotnet: ```sudo pacman -Sy dotnet-sdk dotnet-runtime aspnet-runtime```.