From 9936f69481d5f7a43cfde026b593b9ac35e039ce Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 8 May 2017 11:27:21 -0400 Subject: [PATCH] support access all for collection user details --- src/Api/Controllers/CollectionsController.cs | 12 +++++--- .../Api/Response/CollectionResponseModel.cs | 29 +++++++++++++++++-- ...OrganizationUserCollectionResponseModel.cs | 2 -- .../Data/CollectionUserCollectionDetails.cs | 3 +- .../SqlServer/CipherRepository.cs | 2 +- .../SqlServer/OrganizationUserRepository.cs | 3 +- .../Cipher_ReadCanEditByIdUserId.sql | 2 +- ...tionUserCollectionDetails_ReadByUserId.sql | 8 ++--- .../CollectionUserCollectionDetailsView.sql | 20 ++++++++----- 9 files changed, 56 insertions(+), 25 deletions(-) diff --git a/src/Api/Controllers/CollectionsController.cs b/src/Api/Controllers/CollectionsController.cs index 2f4bf88e6..bfa681d29 100644 --- a/src/Api/Controllers/CollectionsController.cs +++ b/src/Api/Controllers/CollectionsController.cs @@ -16,17 +16,20 @@ namespace Bit.Api.Controllers public class CollectionsController : Controller { private readonly ICollectionRepository _collectionRepository; + private readonly ICollectionUserRepository _collectionUserRepository; private readonly ICollectionService _collectionService; private readonly IUserService _userService; private readonly CurrentContext _currentContext; public CollectionsController( ICollectionRepository collectionRepository, + ICollectionUserRepository collectionUserRepository, ICollectionService collectionService, IUserService userService, CurrentContext currentContext) { _collectionRepository = collectionRepository; + _collectionUserRepository = collectionUserRepository; _collectionService = collectionService; _userService = userService; _currentContext = currentContext; @@ -59,11 +62,12 @@ namespace Bit.Api.Controllers } [HttpGet("~/collections")] - public async Task> GetUser() + public async Task> GetUser() { - var collections = await _collectionRepository.GetManyByUserIdAsync(_userService.GetProperUserId(User).Value); - var responses = collections.Select(c => new CollectionResponseModel(c)); - return new ListResponseModel(responses); + var collections = await _collectionUserRepository.GetManyDetailsByUserIdAsync( + _userService.GetProperUserId(User).Value); + var responses = collections.Select(c => new CollectionUserDetailsResponseModel(c)); + return new ListResponseModel(responses); } [HttpPost("")] diff --git a/src/Core/Models/Api/Response/CollectionResponseModel.cs b/src/Core/Models/Api/Response/CollectionResponseModel.cs index 501c20335..ed7233494 100644 --- a/src/Core/Models/Api/Response/CollectionResponseModel.cs +++ b/src/Core/Models/Api/Response/CollectionResponseModel.cs @@ -1,12 +1,26 @@ using System; using Bit.Core.Models.Table; +using Bit.Core.Models.Data; namespace Bit.Core.Models.Api { public class CollectionResponseModel : ResponseModel { - public CollectionResponseModel(Collection collection) - : base("collection") + public CollectionResponseModel(Collection collection, string obj = "collection") + : base(obj) + { + if(collection == null) + { + throw new ArgumentNullException(nameof(collection)); + } + + Id = collection.Id.ToString(); + OrganizationId = collection.OrganizationId.ToString(); + Name = collection.Name; + } + + public CollectionResponseModel(CollectionUserCollectionDetails collection, string obj = "collection") + : base(obj) { if(collection == null) { @@ -22,4 +36,15 @@ namespace Bit.Core.Models.Api public string OrganizationId { get; set; } public string Name { get; set; } } + + public class CollectionUserDetailsResponseModel : CollectionResponseModel + { + public CollectionUserDetailsResponseModel(CollectionUserCollectionDetails collection) + : base(collection, "collectionUserDetails") + { + ReadOnly = collection.ReadOnly; + } + + public bool ReadOnly { get; set; } + } } diff --git a/src/Core/Models/Api/Response/OrganizationUserCollectionResponseModel.cs b/src/Core/Models/Api/Response/OrganizationUserCollectionResponseModel.cs index 108be4525..796769ffa 100644 --- a/src/Core/Models/Api/Response/OrganizationUserCollectionResponseModel.cs +++ b/src/Core/Models/Api/Response/OrganizationUserCollectionResponseModel.cs @@ -16,13 +16,11 @@ namespace Bit.Core.Models.Api Id = details.Id.ToString(); Name = details.Name; - CollectionId = details.CollectionId.ToString(); ReadOnly = details.ReadOnly; } public string Id { get; set; } public string Name { get; set; } - public string CollectionId { get; set; } public bool ReadOnly { get; set; } } } diff --git a/src/Core/Models/Data/CollectionUserCollectionDetails.cs b/src/Core/Models/Data/CollectionUserCollectionDetails.cs index fd9f63f47..d4fd03cfe 100644 --- a/src/Core/Models/Data/CollectionUserCollectionDetails.cs +++ b/src/Core/Models/Data/CollectionUserCollectionDetails.cs @@ -5,9 +5,8 @@ namespace Bit.Core.Models.Data public class CollectionUserCollectionDetails { public Guid Id { get; set; } - public Guid OrganizationUserId { get; set; } + public Guid OrganizationId { get; set; } public string Name { get; set; } - public Guid CollectionId { get; set; } public bool ReadOnly { get; set; } } } diff --git a/src/Core/Repositories/SqlServer/CipherRepository.cs b/src/Core/Repositories/SqlServer/CipherRepository.cs index a980003a8..05af5dd73 100644 --- a/src/Core/Repositories/SqlServer/CipherRepository.cs +++ b/src/Core/Repositories/SqlServer/CipherRepository.cs @@ -41,7 +41,7 @@ namespace Bit.Core.Repositories.SqlServer { var result = await connection.QueryFirstOrDefaultAsync( $"[{Schema}].[Cipher_ReadCanEditByIdUserId]", - new { UserId = userId, CipherId = cipherId }, + new { UserId = userId, Id = cipherId }, commandType: CommandType.StoredProcedure); return result; diff --git a/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs b/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs index daa00e682..4ea14545b 100644 --- a/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs +++ b/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs @@ -113,7 +113,8 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task>> GetDetailsByIdAsync(Guid id) + public async Task>> + GetDetailsByIdAsync(Guid id) { using(var connection = new SqlConnection(ConnectionString)) { diff --git a/src/Sql/dbo/Stored Procedures/Cipher_ReadCanEditByIdUserId.sql b/src/Sql/dbo/Stored Procedures/Cipher_ReadCanEditByIdUserId.sql index b56a3e478..48765d179 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_ReadCanEditByIdUserId.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_ReadCanEditByIdUserId.sql @@ -1,4 +1,4 @@ -CREATE PROCEDURE [dbo].[Cipher_CanEditByIdUserId] +CREATE PROCEDURE [dbo].[Cipher_ReadCanEditByIdUserId] @Id UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER AS diff --git a/src/Sql/dbo/Stored Procedures/CollectionUserCollectionDetails_ReadByUserId.sql b/src/Sql/dbo/Stored Procedures/CollectionUserCollectionDetails_ReadByUserId.sql index 31a4630c4..9514c94dd 100644 --- a/src/Sql/dbo/Stored Procedures/CollectionUserCollectionDetails_ReadByUserId.sql +++ b/src/Sql/dbo/Stored Procedures/CollectionUserCollectionDetails_ReadByUserId.sql @@ -5,11 +5,9 @@ BEGIN SET NOCOUNT ON SELECT - CU.* + * FROM - [dbo].[CollectionUserCollectionDetailsView] CU - INNER JOIN - [OrganizationUser] OU ON CU.[OrganizationUserId] = OU.[Id] + [dbo].[CollectionUserCollectionDetailsView] WHERE - OU.[UserId] = @UserId + [UserId] = @UserId END \ No newline at end of file diff --git a/src/Sql/dbo/Views/CollectionUserCollectionDetailsView.sql b/src/Sql/dbo/Views/CollectionUserCollectionDetailsView.sql index df996ac14..161821237 100644 --- a/src/Sql/dbo/Views/CollectionUserCollectionDetailsView.sql +++ b/src/Sql/dbo/Views/CollectionUserCollectionDetailsView.sql @@ -1,12 +1,18 @@ CREATE VIEW [dbo].[CollectionUserCollectionDetailsView] AS SELECT - CU.[Id], - CU.[OrganizationUserId], - S.[Name], - S.[Id] CollectionId, - CU.[ReadOnly] + C.[Id] Id, + C.[OrganizationId], + C.[Name], + OU.[UserId], + OU.[Id] AS [OrganizationUserId], + CASE WHEN OU.[AccessAll] = 0 AND CU.[ReadOnly] = 1 THEN 1 ELSE 0 END [ReadOnly] FROM - [dbo].[CollectionUser] CU + [dbo].[Collection] C INNER JOIN - [dbo].[Collection] S ON S.[Id] = CU.[CollectionId] \ No newline at end of file + [dbo].[OrganizationUser] OU ON C.[OrganizationId] = OU.[OrganizationId] +LEFT JOIN + [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = [OU].[Id] +WHERE + OU.[AccessAll] = 1 + OR CU.[Id] IS NOT NULL \ No newline at end of file