From d03421fe4b25f8a598d25e4de27251f08d3096c8 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 13 Nov 2017 10:06:54 -0500 Subject: [PATCH] fix to user already exists checks --- .../IOrganizationUserRepository.cs | 2 +- .../SqlServer/OrganizationUserRepository.cs | 10 ++--- .../Implementations/OrganizationService.cs | 10 +++-- ...nizationUser_ReadByOrganizationIdEmail.sql | 18 ++++++--- .../DbScripts/2017-11-13_IndexTuning.sql | 38 ++++++++++++++++++- 5 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/Core/Repositories/IOrganizationUserRepository.cs b/src/Core/Repositories/IOrganizationUserRepository.cs index 8648c075d6..11228869d0 100644 --- a/src/Core/Repositories/IOrganizationUserRepository.cs +++ b/src/Core/Repositories/IOrganizationUserRepository.cs @@ -14,7 +14,7 @@ namespace Bit.Core.Repositories Task GetCountByOnlyOwnerAsync(Guid userId); Task> GetManyByUserAsync(Guid userId); Task> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type); - Task GetByOrganizationAsync(Guid organizationId, string email); + Task GetCountByOrganizationAsync(Guid organizationId, string email, bool onlyRegisteredUsers); Task GetByOrganizationAsync(Guid organizationId, Guid userId); Task>> GetByIdWithCollectionsAsync(Guid id); Task> GetManyDetailsByOrganizationAsync(Guid organizationId); diff --git a/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs b/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs index 754bf8535c..6ebe35e67d 100644 --- a/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs +++ b/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs @@ -62,16 +62,16 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task GetByOrganizationAsync(Guid organizationId, string email) + public async Task GetCountByOrganizationAsync(Guid organizationId, string email, bool onlyRegisteredUsers) { using(var connection = new SqlConnection(ConnectionString)) { - var results = await connection.QueryAsync( - "[dbo].[OrganizationUser_ReadByOrganizationIdEmail]", - new { OrganizationId = organizationId, Email = email }, + var result = await connection.ExecuteScalarAsync( + "[dbo].[OrganizationUser_ReadCountByOrganizationIdEmail]", + new { OrganizationId = organizationId, Email = email, OnlyUsers = onlyRegisteredUsers }, commandType: CommandType.StoredProcedure); - return results.SingleOrDefault(); + return result; } } diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index b0a5a05d82..747313737e 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -857,8 +857,9 @@ namespace Bit.Core.Services foreach(var email in emails) { // Make sure user is not already invited - var existingOrgUser = await _organizationUserRepository.GetByOrganizationAsync(organizationId, email); - if(existingOrgUser != null) + var existingOrgUserCount = await _organizationUserRepository.GetCountByOrganizationAsync( + organizationId, email, false); + if(existingOrgUserCount > 0) { throw new BadRequestException("User already invited."); } @@ -940,8 +941,9 @@ namespace Bit.Core.Services } } - var existingOrgUser = await _organizationUserRepository.GetByOrganizationAsync(orgUser.OrganizationId, user.Email); - if(existingOrgUser != null) + var existingOrgUserCount = await _organizationUserRepository.GetCountByOrganizationAsync( + orgUser.OrganizationId, user.Email, true); + if(existingOrgUserCount > 0) { throw new BadRequestException("You are already part of this organization."); } diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadByOrganizationIdEmail.sql b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadByOrganizationIdEmail.sql index b9ba7a515f..0808543ae9 100644 --- a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadByOrganizationIdEmail.sql +++ b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadByOrganizationIdEmail.sql @@ -1,15 +1,21 @@ -CREATE PROCEDURE [dbo].[OrganizationUser_ReadByOrganizationIdEmail] +CREATE PROCEDURE [dbo].[OrganizationUser_ReadCountByOrganizationIdEmail] @OrganizationId UNIQUEIDENTIFIER, - @Email NVARCHAR(50) + @Email NVARCHAR(50), + @OnlyUsers BIT AS BEGIN SET NOCOUNT ON SELECT - * + COUNT(1) FROM - [dbo].[OrganizationUserView] + [dbo].[OrganizationUser] OU + LEFT JOIN + [dbo].[User] U ON OU.[UserId] = U.[Id] WHERE - [OrganizationId] = @OrganizationId - AND [Email] = @Email + OU.[OrganizationId] = @OrganizationId + AND ( + (@OnlyUsers = 0 AND (OU.[Email] = @Email OR U.[Email] = @Email)) + OR (@OnlyUsers = 1 AND U.[Email] = @Email) + ) END \ No newline at end of file diff --git a/util/Setup/DbScripts/2017-11-13_IndexTuning.sql b/util/Setup/DbScripts/2017-11-13_IndexTuning.sql index f33dcf0386..ec968eff59 100644 --- a/util/Setup/DbScripts/2017-11-13_IndexTuning.sql +++ b/util/Setup/DbScripts/2017-11-13_IndexTuning.sql @@ -1,4 +1,39 @@ -IF EXISTS ( +IF OBJECT_ID('[dbo].[OrganizationUser_ReadByOrganizationIdEmail]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[OrganizationUser_ReadByOrganizationIdEmail] +END +GO + +IF OBJECT_ID('[dbo].[OrganizationUser_ReadCountByOrganizationIdEmail]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[OrganizationUser_ReadCountByOrganizationIdEmail] +END +GO + +CREATE PROCEDURE [dbo].[OrganizationUser_ReadCountByOrganizationIdEmail] + @OrganizationId UNIQUEIDENTIFIER, + @Email NVARCHAR(50), + @OnlyUsers BIT +AS +BEGIN + SET NOCOUNT ON + + SELECT + COUNT(1) + FROM + [dbo].[OrganizationUser] OU + LEFT JOIN + [dbo].[User] U ON OU.[UserId] = U.[Id] + WHERE + OU.[OrganizationId] = @OrganizationId + AND ( + (@OnlyUsers = 0 AND (OU.[Email] = @Email OR U.[Email] = @Email)) + OR (@OnlyUsers = 1 AND U.[Email] = @Email) + ) +END +GO + +IF EXISTS ( SELECT * FROM sys.indexes WHERE [Name]='IX_Cipher_UserId_Type' AND object_id = OBJECT_ID('[dbo].[Cipher]') ) @@ -39,4 +74,3 @@ BEGIN INCLUDE ([AccessAll]) END GO -