Compare commits
2 Commits
9c6fc0460b
...
a1c336e4d6
Author | SHA1 | Date | |
---|---|---|---|
a1c336e4d6 | |||
da1339347f |
108
ActiveAllocator.API/Controllers/IntegrationController.cs
Normal file
108
ActiveAllocator.API/Controllers/IntegrationController.cs
Normal file
@ -0,0 +1,108 @@
|
||||
namespace ActiveAllocator.API.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ActiveAllocator.API.Models.Accounts;
|
||||
using ActiveAllocator.API.Services;
|
||||
using ActiveAllocator.API.Config;
|
||||
using System.Collections.Generic;
|
||||
using ActiveAllocator.API.Entities;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class IntegrationController : ControllerBase
|
||||
{
|
||||
private IIntegrationService _integrationService;
|
||||
private IMapper _mapper;
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public IntegrationController(
|
||||
IIntegrationService integrationService,
|
||||
IMapper mapper,
|
||||
IOptions<AppSettings> appSettings)
|
||||
{
|
||||
_integrationService = integrationService;
|
||||
_mapper = mapper;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetAll()
|
||||
{
|
||||
List<IntegrationDTO> DTOs = new();
|
||||
|
||||
foreach (var item in _integrationService.GetAll())
|
||||
DTOs.Add(_mapper.Map<Integration, IntegrationDTO>(item));
|
||||
|
||||
return Ok(DTOs);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetById(int id)
|
||||
{
|
||||
return Ok(_mapper.Map<Integration, IntegrationDTO>(_integrationService.GetById(id)));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody]IntegrationCreateRequest model)
|
||||
{
|
||||
_integrationService.Create(model);
|
||||
return Ok(new { message = "integration created" });
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]IntegrationUpdateRequest model)
|
||||
{
|
||||
_integrationService.Update(id, model);
|
||||
return Ok(new { message = "integration updated" });
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
_integrationService.Delete(id);
|
||||
return Ok(new { message = "integration deleted" });
|
||||
}
|
||||
|
||||
[HttpGet("Accounts")]
|
||||
public IActionResult GetAllAccounts(int? integration_id = null)
|
||||
{
|
||||
List<IntegrationAccountDTO> DTOs = new();
|
||||
|
||||
foreach (var item in _integrationService.GetAllAccounts(integration_id))
|
||||
DTOs.Add(_mapper.Map<IntegrationAccount, IntegrationAccountDTO>(item));
|
||||
|
||||
return Ok(DTOs);
|
||||
}
|
||||
|
||||
[HttpGet("Accounts/{account_id}")]
|
||||
public IActionResult GetAccountById(int account_id)
|
||||
{
|
||||
return Ok(_mapper.Map<IntegrationAccount, IntegrationAccountDTO>(_integrationService.GetAccountById(account_id)));
|
||||
}
|
||||
|
||||
[HttpPost("Accounts")]
|
||||
public IActionResult CreateAccount([FromBody]IntegrationAccountCreateRequest model)
|
||||
{
|
||||
_integrationService.CreateAccount(model);
|
||||
return Ok(new { message = "integration account created" });
|
||||
}
|
||||
|
||||
[HttpPut("Accounts/{id}")]
|
||||
public IActionResult UpdateAccount(int id, [FromBody]IntegrationAccountUpdateRequest model)
|
||||
{
|
||||
_integrationService.UpdateAccount(id, model);
|
||||
return Ok(new { message = "integration account updated" });
|
||||
}
|
||||
|
||||
[HttpDelete("Accounts/{id}")]
|
||||
public IActionResult DeleteAccount(int id)
|
||||
{
|
||||
_integrationService.DeleteAccount(id);
|
||||
return Ok(new { message = "integration account deleted" });
|
||||
}
|
||||
}
|
14
ActiveAllocator.API/Entities/Integration.cs
Normal file
14
ActiveAllocator.API/Entities/Integration.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using ActiveAllocator.API.Enums;
|
||||
|
||||
namespace ActiveAllocator.API.Entities;
|
||||
|
||||
public class Integration
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string ApiUrl { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public IntegrationType Type { get; set; }
|
||||
}
|
14
ActiveAllocator.API/Entities/IntegrationAccount.cs
Normal file
14
ActiveAllocator.API/Entities/IntegrationAccount.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using ActiveAllocator.API.Enums;
|
||||
|
||||
namespace ActiveAllocator.API.Entities;
|
||||
|
||||
public class IntegrationAccount
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public Integration Integration { get; set; }
|
||||
public Account LinkedAccount { get; set; }
|
||||
}
|
10
ActiveAllocator.API/Enums/IntegrationTypes.cs
Normal file
10
ActiveAllocator.API/Enums/IntegrationTypes.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ActiveAllocator.API.Enums;
|
||||
|
||||
public enum IntegrationType
|
||||
{
|
||||
AccountImporter,
|
||||
TransactionImporter,
|
||||
TransactionMapper,
|
||||
}
|
@ -10,6 +10,7 @@ using ActiveAllocator.API.Services;
|
||||
using System.Runtime.Serialization;
|
||||
using ActiveAllocator.API.Models.Transactions;
|
||||
using ActiveAllocator.API.Models.Autoclass;
|
||||
using ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
public class AutoMapperProfile : Profile
|
||||
{
|
||||
@ -207,5 +208,11 @@ public class AutoMapperProfile : Profile
|
||||
CreateMap<AutoclassRule, AutoclassRuleDTO>()
|
||||
.ForMember(dest => dest.AccountId, opt => opt.MapFrom(src => src.Account.Id));
|
||||
|
||||
// Envelope -> EnvelopeDTO
|
||||
CreateMap<Integration, IntegrationDTO>();
|
||||
CreateMap<IntegrationAccount, IntegrationAccountDTO>()
|
||||
.ForMember(dest => dest.IntegrationId, opt => opt.MapFrom(src => src.Integration.Id))
|
||||
.ForMember(dest => dest.LinkedAccountId, opt => opt.MapFrom(src => src.LinkedAccount.Id));
|
||||
|
||||
}
|
||||
}
|
@ -454,4 +454,6 @@ public class DataContext : DbContext
|
||||
public DbSet<AutoclassRule> AutoclassRules { get; set; }
|
||||
public DbSet<AutoclassExpression> AutoclassExpressions { get; set; }
|
||||
public DbSet<AutoclassChange> AutoclassChanges { get; set; }
|
||||
public DbSet<Integration> Integrations { get; set; }
|
||||
public DbSet<IntegrationAccount> IntegrationAccounts { get; set; }
|
||||
}
|
606
ActiveAllocator.API/Migrations/20240405024649_Integrations.Designer.cs
generated
Normal file
606
ActiveAllocator.API/Migrations/20240405024649_Integrations.Designer.cs
generated
Normal file
@ -0,0 +1,606 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveAllocator.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 ActiveAllocator.API.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20240405024649_Integrations")]
|
||||
partial class Integrations
|
||||
{
|
||||
/// <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("ActiveAllocator.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<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CurrencyId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ExternalAccountNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastActivity")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("VirtualBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassChange", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("AutoclassRuleId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Field")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AutoclassRuleId");
|
||||
|
||||
b.ToTable("AutoclassChanges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassExpression", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("AutoclassRuleId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("CompareOperator")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("TransactionField")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AutoclassRuleId");
|
||||
|
||||
b.ToTable("AutoclassExpressions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassRule", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("AutoclassRules");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.CurrencyType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DecimalPlaces")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Envelope", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Balance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("IsPersistant")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("LastTriggeredOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<TimeSpan>("Period")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("Envelopes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.EnvelopeFundingMethod", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("EnvelopeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Mode")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("PeriodsToLookback")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EnvelopeId");
|
||||
|
||||
b.ToTable("EnvelopeFundingMethods");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Integration", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ApiUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Version")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Integrations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.IntegrationAccount", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ApiKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("IntegrationId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("LinkedAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IntegrationId");
|
||||
|
||||
b.HasIndex("LinkedAccountId");
|
||||
|
||||
b.ToTable("IntegrationAccounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Operation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("AbsoluteValue")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("HistoricLookbackDepth")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<TimeSpan>("HistoricPeriod")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("HistoricStatistic")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Mode")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Negative")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Percentage")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.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<int?>("CreditEnvelopeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("CurrencyTypeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int?>("DebitAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int?>("DebitEnvelopeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEnvelopeFundingTransaction")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsPending")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<List<string>>("Tags")
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreditAccountId");
|
||||
|
||||
b.HasIndex("CreditEnvelopeId");
|
||||
|
||||
b.HasIndex("CurrencyTypeId");
|
||||
|
||||
b.HasIndex("DebitAccountId");
|
||||
|
||||
b.HasIndex("DebitEnvelopeId");
|
||||
|
||||
b.ToTable("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ApiKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Role")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Account", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.CurrencyType", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.User", null)
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassChange", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.AutoclassRule", null)
|
||||
.WithMany("Changes")
|
||||
.HasForeignKey("AutoclassRuleId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassExpression", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.AutoclassRule", null)
|
||||
.WithMany("Expressions")
|
||||
.HasForeignKey("AutoclassRuleId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassRule", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "Account")
|
||||
.WithMany()
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Envelope", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "Account")
|
||||
.WithMany("Envelopes")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.EnvelopeFundingMethod", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Envelope", "Envelope")
|
||||
.WithMany("FundingMethods")
|
||||
.HasForeignKey("EnvelopeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Envelope");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.IntegrationAccount", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Integration", "Integration")
|
||||
.WithMany()
|
||||
.HasForeignKey("IntegrationId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "LinkedAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("LinkedAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Integration");
|
||||
|
||||
b.Navigation("LinkedAccount");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Transaction", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "CreditAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreditAccountId");
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.Envelope", "CreditEnvelope")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreditEnvelopeId");
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.CurrencyType", "CurrencyType")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyTypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "DebitAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("DebitAccountId");
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.Envelope", "DebitEnvelope")
|
||||
.WithMany()
|
||||
.HasForeignKey("DebitEnvelopeId");
|
||||
|
||||
b.Navigation("CreditAccount");
|
||||
|
||||
b.Navigation("CreditEnvelope");
|
||||
|
||||
b.Navigation("CurrencyType");
|
||||
|
||||
b.Navigation("DebitAccount");
|
||||
|
||||
b.Navigation("DebitEnvelope");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Account", b =>
|
||||
{
|
||||
b.Navigation("Envelopes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.AutoclassRule", b =>
|
||||
{
|
||||
b.Navigation("Changes");
|
||||
|
||||
b.Navigation("Expressions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Envelope", b =>
|
||||
{
|
||||
b.Navigation("FundingMethods");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ActiveAllocator.API.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Integrations : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Integrations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Version = table.Column<string>(type: "text", nullable: false),
|
||||
ApiUrl = table.Column<string>(type: "text", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
Type = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Integrations", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "IntegrationAccounts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
ApiKey = table.Column<string>(type: "text", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
IntegrationId = table.Column<int>(type: "integer", nullable: false),
|
||||
LinkedAccountId = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_IntegrationAccounts", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_IntegrationAccounts_Accounts_LinkedAccountId",
|
||||
column: x => x.LinkedAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_IntegrationAccounts_Integrations_IntegrationId",
|
||||
column: x => x.IntegrationId,
|
||||
principalTable: "Integrations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_IntegrationAccounts_IntegrationId",
|
||||
table: "IntegrationAccounts",
|
||||
column: "IntegrationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_IntegrationAccounts_LinkedAccountId",
|
||||
table: "IntegrationAccounts",
|
||||
column: "LinkedAccountId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "IntegrationAccounts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Integrations");
|
||||
}
|
||||
}
|
||||
}
|
@ -245,6 +245,71 @@ namespace ActiveAllocator.API.Migrations
|
||||
b.ToTable("EnvelopeFundingMethods");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Integration", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ApiUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Version")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Integrations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.IntegrationAccount", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ApiKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("IntegrationId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("LinkedAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IntegrationId");
|
||||
|
||||
b.HasIndex("LinkedAccountId");
|
||||
|
||||
b.ToTable("IntegrationAccounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Operation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -457,6 +522,25 @@ namespace ActiveAllocator.API.Migrations
|
||||
b.Navigation("Envelope");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.IntegrationAccount", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Integration", "Integration")
|
||||
.WithMany()
|
||||
.HasForeignKey("IntegrationId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "LinkedAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("LinkedAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Integration");
|
||||
|
||||
b.Navigation("LinkedAccount");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ActiveAllocator.API.Entities.Transaction", b =>
|
||||
{
|
||||
b.HasOne("ActiveAllocator.API.Entities.Account", "CreditAccount")
|
||||
|
@ -0,0 +1,11 @@
|
||||
namespace ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
public class IntegrationAccountCreateRequest
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string MFAKey { get; set; }
|
||||
public int IntegrationId { get; set; }
|
||||
public int LinkedAccountId { get; set; }
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using ActiveAllocator.API.Enums;
|
||||
|
||||
namespace ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
public class IntegrationAccountDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public int IntegrationId { get; set; }
|
||||
public int LinkedAccountId { get; set; }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
public class IntegrationAccountUpdateRequest
|
||||
{
|
||||
public string Name { get; set; } = null;
|
||||
public string Username { get; set; } = null;
|
||||
public string Password { get; set; } = null;
|
||||
public string MFAKey { get; set; } = null;
|
||||
//public int? IntegrationId { get; set; } = null;
|
||||
public int? LinkedAccountId { get; set; } = null;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
namespace ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.InteropServices;
|
||||
using ActiveAllocator.API.Entities;
|
||||
using ActiveAllocator.API.Enums;
|
||||
|
||||
public class IntegrationCreateRequest
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string ApiUrl { get; set; }
|
||||
public IntegrationType Type { get; set; }
|
||||
}
|
14
ActiveAllocator.API/Models/Integrations/IntegrationDTO.cs
Normal file
14
ActiveAllocator.API/Models/Integrations/IntegrationDTO.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using ActiveAllocator.API.Enums;
|
||||
|
||||
namespace ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
public class IntegrationDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string ApiUrl { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public IntegrationType Type { get; set; }
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
namespace ActiveAllocator.API.Models.Integrations;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ActiveAllocator.API.Entities;
|
||||
using ActiveAllocator.API.Enums;
|
||||
|
||||
public class IntegrationUpdateRequest
|
||||
{
|
||||
public string Name { get; set; } = null;
|
||||
public string Version { get; set; } = null;
|
||||
public string ApiUrl { get; set; } = null;
|
||||
public IntegrationType? Type { get; set; } = null;
|
||||
}
|
224
ActiveAllocator.API/Services/IntegrationService.cs
Normal file
224
ActiveAllocator.API/Services/IntegrationService.cs
Normal file
@ -0,0 +1,224 @@
|
||||
namespace ActiveAllocator.API.Services;
|
||||
|
||||
using ActiveAllocator.API.Entities;
|
||||
using ActiveAllocator.API.Config;
|
||||
using ActiveAllocator.API.Models.Integrations;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public interface IIntegrationService
|
||||
{
|
||||
IEnumerable<Integration> GetAll();
|
||||
IEnumerable<IntegrationAccount> GetAllAccounts(int? integrationId = null);
|
||||
Integration GetById(int integrationId);
|
||||
IntegrationAccount GetAccountById(int accountId);
|
||||
void Create(IntegrationCreateRequest model);
|
||||
void CreateAccount(IntegrationAccountCreateRequest model);
|
||||
void Update(int integrationId, IntegrationUpdateRequest model);
|
||||
void UpdateAccount(int integrationAccountId, IntegrationAccountUpdateRequest model);
|
||||
void Delete(int integrationId);
|
||||
void DeleteAccount(int integrationAccountId);
|
||||
}
|
||||
|
||||
public class IntegrationService : IIntegrationService
|
||||
{
|
||||
private DataContext _context;
|
||||
|
||||
public IntegrationService(
|
||||
DataContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public IEnumerable<Integration> GetAll()
|
||||
{
|
||||
return _context.Integrations;
|
||||
}
|
||||
|
||||
public IEnumerable<IntegrationAccount> GetAllAccounts(int? integrationId = null)
|
||||
{
|
||||
if (integrationId.HasValue)
|
||||
return _context.IntegrationAccounts
|
||||
.Include(a => a.Integration)
|
||||
.Include(a => a.LinkedAccount)
|
||||
.Where(a => a.Integration.Id == integrationId.Value);
|
||||
else
|
||||
return _context.IntegrationAccounts
|
||||
.Include(a => a.Integration)
|
||||
.Include(a => a.LinkedAccount);
|
||||
}
|
||||
|
||||
public Integration GetById(int integrationId)
|
||||
{
|
||||
return GetIntegration(integrationId);
|
||||
}
|
||||
|
||||
public IntegrationAccount GetAccountById(int accountId)
|
||||
{
|
||||
return GetIntegrationAccount(accountId);
|
||||
}
|
||||
|
||||
public void Create(IntegrationCreateRequest model)
|
||||
{
|
||||
if (_context.Integrations.Any(a => a.Name.ToUpper() == model.Name.ToUpper()))
|
||||
throw new AppException("Integration with name '" + model.Name + "' already exists");
|
||||
|
||||
if (_context.Integrations.Any(a => a.ApiUrl.ToUpper() == model.ApiUrl.ToUpper()))
|
||||
throw new AppException("Integration with API Url '" + model.ApiUrl + "' already exists");
|
||||
|
||||
Integration integration = new Integration {
|
||||
Name = model.Name,
|
||||
Version = model.Version,
|
||||
ApiUrl = model.ApiUrl,
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
Type = model.Type
|
||||
};
|
||||
|
||||
_context.Integrations.Add(integration);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void CreateAccount(IntegrationAccountCreateRequest model)
|
||||
{
|
||||
// Validate model info
|
||||
if (_context.IntegrationAccounts
|
||||
.Include(a => a.Integration)
|
||||
.Any(a => a.Name.ToUpper() == model.Name.ToUpper() && a.Integration.Id == model.IntegrationId))
|
||||
throw new AppException($"IntegrationAccount with name '{model.Name}' already exists on integration '{model.IntegrationId}'");
|
||||
|
||||
Integration integration = _context.Integrations.Find(model.IntegrationId) ?? throw new AppException($"Integration with id '{model.IntegrationId}' not found");
|
||||
|
||||
Account account = _context.Accounts.Find(model.LinkedAccountId) ?? throw new AppException($"Account with id '{model.LinkedAccountId}' not found");
|
||||
|
||||
// Get API Key from integration
|
||||
string apiKey = RegisterRemoteIntegrationAccount(model.Username, model.Password, model.MFAKey);
|
||||
|
||||
// Create entity and insert into database
|
||||
IntegrationAccount integrationAccount = new IntegrationAccount {
|
||||
Name = model.Name,
|
||||
ApiKey = apiKey,
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
Integration = integration,
|
||||
LinkedAccount = account
|
||||
};
|
||||
|
||||
_context.IntegrationAccounts.Add(integrationAccount);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void Update(int integrationId, IntegrationUpdateRequest model)
|
||||
{
|
||||
Integration integration = GetIntegration(integrationId);
|
||||
|
||||
// validate
|
||||
if (model.Name != integration.Name && _context.Integrations.Any(x => x.Name == model.Name))
|
||||
throw new AppException("Integration with the name '" + model.Name + "' already exists");
|
||||
|
||||
// validate
|
||||
if (model.ApiUrl != integration.ApiUrl && _context.Integrations.Any(x => x.ApiUrl == model.ApiUrl))
|
||||
throw new AppException("Integration with the API Url '" + model.ApiUrl + "' already exists");
|
||||
|
||||
// Name
|
||||
if (!string.IsNullOrWhiteSpace(model.Name))
|
||||
integration.Name = model.Name;
|
||||
|
||||
// Api Url
|
||||
if (!string.IsNullOrWhiteSpace(model.ApiUrl))
|
||||
integration.ApiUrl = model.ApiUrl;
|
||||
|
||||
// Version
|
||||
if (!string.IsNullOrWhiteSpace(model.Version))
|
||||
integration.Version = model.Version;
|
||||
|
||||
// Types
|
||||
if (model.Type.HasValue)
|
||||
{
|
||||
integration.Type = model.Type.Value;
|
||||
}
|
||||
|
||||
_context.Integrations.Update(integration);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void UpdateAccount(int integrationAccountId, IntegrationAccountUpdateRequest model)
|
||||
{
|
||||
IntegrationAccount integrationAccount = GetIntegrationAccount(integrationAccountId);
|
||||
|
||||
// Check if new name is valid
|
||||
if (model.Name != integrationAccount.Name && _context.IntegrationAccounts
|
||||
.Include(a => a.Integration)
|
||||
.Any(a => a.Name.ToUpper() == model.Name.ToUpper() && a.Integration.Id == integrationAccount.Integration.Id))
|
||||
throw new AppException($"IntegrationAccount with name '{model.Name}' already exists on integration '{integrationAccount.Integration.Id}'");
|
||||
|
||||
// Check if username, password, and MFAKey are set
|
||||
// If so, delete integration user, and remake one, update API key
|
||||
|
||||
if (model.LinkedAccountId.HasValue)
|
||||
{
|
||||
Account account = _context.Accounts.Find(model.LinkedAccountId.Value) ?? throw new AppException($"Could not find the account specified by LinkedAccountId");
|
||||
integrationAccount.LinkedAccount = account;
|
||||
}
|
||||
|
||||
if (model.Username != null || model.Password != null || model.MFAKey != null)
|
||||
{
|
||||
if (model.Username == null || model.Password == null || model.MFAKey == null)
|
||||
throw new AppException($"IntegrationAccount credential change requires all new credentials");
|
||||
|
||||
string apiKey = UpdateRemoteIntegrationAccount(integrationAccount.Id, model.Username, model.Password, model.MFAKey);
|
||||
|
||||
integrationAccount.ApiKey = apiKey;
|
||||
}
|
||||
|
||||
_context.IntegrationAccounts.Update(integrationAccount);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(int integrationId)
|
||||
{
|
||||
var integration = GetIntegration(integrationId);
|
||||
_context.Integrations.Remove(integration);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void DeleteAccount(int integrationAccountId)
|
||||
{
|
||||
var integrationAccount = _context.IntegrationAccounts.Find(integrationAccountId) ?? throw new AppException($"Could not find the integration account specified to delete");
|
||||
DeleteRemoteIntegrationAccount(integrationAccount.Id);
|
||||
_context.IntegrationAccounts.Remove(integrationAccount);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
||||
private string UpdateRemoteIntegrationAccount(int integrationAccountId, string username, string password, string mfaKey)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void DeleteRemoteIntegrationAccount(int integrationAccountId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private string RegisterRemoteIntegrationAccount(string username, string password, string mfaKey)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Integration GetIntegration(int id)
|
||||
{
|
||||
var integration = _context.Integrations.Find(id) ?? throw new KeyNotFoundException("Integration not found");
|
||||
return integration;
|
||||
}
|
||||
|
||||
private IntegrationAccount GetIntegrationAccount(int id)
|
||||
{
|
||||
return _context.IntegrationAccounts
|
||||
.Include(a => a.Integration)
|
||||
.Include(a => a.LinkedAccount)
|
||||
.FirstOrDefault(a => a.Id == id)
|
||||
?? throw new KeyNotFoundException("IntegrationAccount not found");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user