using System.Data; using Bit.Core.AdminConsole.Entities; using Bit.Core.Auth.Entities; using Bit.Core.Entities; using Bit.Core.Models.Data.Organizations; using Bit.Core.Repositories; using Bit.Core.Settings; using Dapper; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Logging; namespace Bit.Infrastructure.Dapper.Repositories; public class OrganizationRepository : Repository, IOrganizationRepository { private readonly ILogger _logger; public OrganizationRepository( GlobalSettings globalSettings, ILogger logger) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString) { _logger = logger; } public OrganizationRepository(string connectionString, string readOnlyConnectionString) : base(connectionString, readOnlyConnectionString) { } public async Task GetByIdentifierAsync(string identifier) { using (var connection = new SqlConnection(ConnectionString)) { var results = await connection.QueryAsync( "[dbo].[Organization_ReadByIdentifier]", new { Identifier = identifier }, commandType: CommandType.StoredProcedure); return results.SingleOrDefault(); } } public async Task> GetManyByEnabledAsync() { using (var connection = new SqlConnection(ConnectionString)) { var results = await connection.QueryAsync( "[dbo].[Organization_ReadByEnabled]", commandType: CommandType.StoredProcedure); return results.ToList(); } } public async Task> GetManyByUserIdAsync(Guid userId) { using (var connection = new SqlConnection(ConnectionString)) { var results = await connection.QueryAsync( "[dbo].[Organization_ReadByUserId]", new { UserId = userId }, commandType: CommandType.StoredProcedure); return results.ToList(); } } public async Task> SearchAsync(string name, string userEmail, bool? paid, int skip, int take) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var results = await connection.QueryAsync( "[dbo].[Organization_Search]", new { Name = name, UserEmail = userEmail, Paid = paid, Skip = skip, Take = take }, commandType: CommandType.StoredProcedure, commandTimeout: 120); return results.ToList(); } } public async Task UpdateStorageAsync(Guid id) { using (var connection = new SqlConnection(ConnectionString)) { await connection.ExecuteAsync( "[dbo].[Organization_UpdateStorage]", new { Id = id }, commandType: CommandType.StoredProcedure, commandTimeout: 180); } } public async Task> GetManyAbilitiesAsync() { using (var connection = new SqlConnection(ConnectionString)) { var results = await connection.QueryAsync( "[dbo].[Organization_ReadAbilities]", commandType: CommandType.StoredProcedure); return results.ToList(); } } public async Task GetByLicenseKeyAsync(string licenseKey) { using (var connection = new SqlConnection(ConnectionString)) { var result = await connection.QueryAsync( "[dbo].[Organization_ReadByLicenseKey]", new { LicenseKey = licenseKey }, commandType: CommandType.StoredProcedure); return result.SingleOrDefault(); } } public async Task GetSelfHostedOrganizationDetailsById(Guid id) { using (var connection = new SqlConnection(ConnectionString)) { var result = await connection.QueryMultipleAsync( "[dbo].[Organization_ReadSelfHostedDetailsById]", new { Id = id }, commandType: CommandType.StoredProcedure); var selfHostOrganization = await result.ReadSingleOrDefaultAsync(); if (selfHostOrganization == null) { return null; } selfHostOrganization.OccupiedSeatCount = await result.ReadSingleAsync(); selfHostOrganization.CollectionCount = await result.ReadSingleAsync(); selfHostOrganization.GroupCount = await result.ReadSingleAsync(); selfHostOrganization.OrganizationUsers = await result.ReadAsync(); selfHostOrganization.Policies = await result.ReadAsync(); selfHostOrganization.SsoConfig = await result.ReadFirstOrDefaultAsync(); selfHostOrganization.ScimConnections = await result.ReadAsync(); return selfHostOrganization; } } public async Task> SearchUnassignedToProviderAsync(string name, string ownerEmail, int skip, int take) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var results = await connection.QueryAsync( "[dbo].[Organization_UnassignedToProviderSearch]", new { Name = name, OwnerEmail = ownerEmail, Skip = skip, Take = take }, commandType: CommandType.StoredProcedure, commandTimeout: 120); return results.ToList(); } } public async Task> GetOwnerEmailAddressesById(Guid organizationId) { _logger.LogInformation("AC-1758: Executing GetOwnerEmailAddressesById (Dapper)"); await using var connection = new SqlConnection(ConnectionString); return await connection.QueryAsync( $"[{Schema}].[{Table}_ReadOwnerEmailAddressesById]", new { OrganizationId = organizationId }, commandType: CommandType.StoredProcedure); } }