From 31b812c01c26f4e697b4f2b97c2ff2dc69bb7804 Mon Sep 17 00:00:00 2001 From: Jared McCannon Date: Wed, 11 Mar 2026 14:16:54 -0500 Subject: [PATCH] Added provider ability --- .../Repositories/IProviderRepository.cs | 1 + .../Repositories/ProviderRepository.cs | 12 ++++++ .../Repositories/ProviderRepository.cs | 17 ++++++++ .../Provider_ReadAbilityById.sql | 15 +++++++ src/Sql/dbo/Views/ProviderAbilityView.sql | 8 ++++ .../Data/Provider/ProviderAbilityTests.cs | 43 +++++++++++++++++++ ..._AddProviderAbilityViewAndReadByIdProc.sql | 26 +++++++++++ 7 files changed, 122 insertions(+) create mode 100644 src/Sql/dbo/Stored Procedures/Provider_ReadAbilityById.sql create mode 100644 src/Sql/dbo/Views/ProviderAbilityView.sql create mode 100644 test/Core.Test/AdminConsole/Models/Data/Provider/ProviderAbilityTests.cs create mode 100644 util/Migrator/DbScripts/2026-03-11_00_AddProviderAbilityViewAndReadByIdProc.sql diff --git a/src/Core/AdminConsole/Repositories/IProviderRepository.cs b/src/Core/AdminConsole/Repositories/IProviderRepository.cs index 8e2eeabaa6dd..d76c4ad14f5d 100644 --- a/src/Core/AdminConsole/Repositories/IProviderRepository.cs +++ b/src/Core/AdminConsole/Repositories/IProviderRepository.cs @@ -13,4 +13,5 @@ public interface IProviderRepository : IRepository Task GetByOrganizationIdAsync(Guid organizationId); Task> SearchAsync(string name, string userEmail, int skip, int take); Task> GetManyAbilitiesAsync(); + Task GetAbilityAsync(Guid id); } diff --git a/src/Infrastructure.Dapper/AdminConsole/Repositories/ProviderRepository.cs b/src/Infrastructure.Dapper/AdminConsole/Repositories/ProviderRepository.cs index f0342729e924..5a8ff286b006 100644 --- a/src/Infrastructure.Dapper/AdminConsole/Repositories/ProviderRepository.cs +++ b/src/Infrastructure.Dapper/AdminConsole/Repositories/ProviderRepository.cs @@ -85,4 +85,16 @@ public async Task> GetManyAbilitiesAsync() return results.ToList(); } } + + public async Task GetAbilityAsync(Guid id) + { + await using var connection = new SqlConnection(ReadOnlyConnectionString); + + var results = await connection.QueryAsync( + "[dbo].[Provider_ReadAbilityById]", + new { Id = id }, + commandType: CommandType.StoredProcedure); + + return results.FirstOrDefault(); + } } diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/ProviderRepository.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/ProviderRepository.cs index 5e3a65f7418c..0450dc19495c 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/ProviderRepository.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/ProviderRepository.cs @@ -105,4 +105,21 @@ public async Task> GetManyAbilitiesAsync() }).ToListAsync(); } } + +#nullable enable + public async Task GetAbilityAsync(Guid id) + { + using (var scope = ServiceScopeFactory.CreateScope()) + { + var dbContext = GetDatabaseContext(scope); + return await GetDbSet(dbContext) + .Where(e => e.Id == id) + .Select(e => new ProviderAbility + { + Id = e.Id, + UseEvents = e.UseEvents, + Enabled = e.Enabled, + }).FirstOrDefaultAsync(); + } + } } diff --git a/src/Sql/dbo/Stored Procedures/Provider_ReadAbilityById.sql b/src/Sql/dbo/Stored Procedures/Provider_ReadAbilityById.sql new file mode 100644 index 000000000000..87e350381854 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/Provider_ReadAbilityById.sql @@ -0,0 +1,15 @@ +CREATE PROCEDURE [dbo].[Provider_ReadAbilityById] + @Id UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + SELECT + [Id], + [UseEvents], + [Enabled] + FROM + [dbo].[ProviderAbilityView] + WHERE + [Id] = @Id +END diff --git a/src/Sql/dbo/Views/ProviderAbilityView.sql b/src/Sql/dbo/Views/ProviderAbilityView.sql new file mode 100644 index 000000000000..6378e8537f26 --- /dev/null +++ b/src/Sql/dbo/Views/ProviderAbilityView.sql @@ -0,0 +1,8 @@ +CREATE VIEW [dbo].[ProviderAbilityView] +AS +SELECT + [Id], + [UseEvents], + [Enabled] +FROM + [dbo].[Provider] diff --git a/test/Core.Test/AdminConsole/Models/Data/Provider/ProviderAbilityTests.cs b/test/Core.Test/AdminConsole/Models/Data/Provider/ProviderAbilityTests.cs new file mode 100644 index 000000000000..9eee9a332e7f --- /dev/null +++ b/test/Core.Test/AdminConsole/Models/Data/Provider/ProviderAbilityTests.cs @@ -0,0 +1,43 @@ +using Bit.Core.AdminConsole.Models.Data.Provider; +using Xunit; + +using ProviderEntity = Bit.Core.AdminConsole.Entities.Provider.Provider; + +namespace Bit.Core.Test.AdminConsole.Models.Data.Provider; + +public class ProviderAbilityTests +{ + [Fact] + public void Constructor_MapsAllProperties() + { + var provider = new ProviderEntity + { + Id = Guid.NewGuid(), + UseEvents = true, + Enabled = true, + }; + + var ability = new ProviderAbility(provider); + + Assert.Equal(provider.Id, ability.Id); + Assert.Equal(provider.UseEvents, ability.UseEvents); + Assert.Equal(provider.Enabled, ability.Enabled); + } + + [Fact] + public void Constructor_DefaultValues() + { + var provider = new ProviderEntity + { + Id = Guid.NewGuid(), + UseEvents = false, + Enabled = false, + }; + + var ability = new ProviderAbility(provider); + + Assert.Equal(provider.Id, ability.Id); + Assert.False(ability.UseEvents); + Assert.False(ability.Enabled); + } +} diff --git a/util/Migrator/DbScripts/2026-03-11_00_AddProviderAbilityViewAndReadByIdProc.sql b/util/Migrator/DbScripts/2026-03-11_00_AddProviderAbilityViewAndReadByIdProc.sql new file mode 100644 index 000000000000..d9de887dc6e6 --- /dev/null +++ b/util/Migrator/DbScripts/2026-03-11_00_AddProviderAbilityViewAndReadByIdProc.sql @@ -0,0 +1,26 @@ +CREATE OR ALTER VIEW [dbo].[ProviderAbilityView] +AS +SELECT + [Id], + [UseEvents], + [Enabled] +FROM + [dbo].[Provider] +GO + +CREATE OR ALTER PROCEDURE [dbo].[Provider_ReadAbilityById] + @Id UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + SELECT + [Id], + [UseEvents], + [Enabled] + FROM + [dbo].[ProviderAbilityView] + WHERE + [Id] = @Id +END +GO