1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-08 14:38:15 -05:00

limit collection scope option when creating cipher

This commit is contained in:
Kyle Spearrin 2018-10-22 14:09:55 -04:00
parent 6641d884f5
commit 0b166a080e
5 changed files with 98 additions and 64 deletions

View File

@ -143,7 +143,7 @@ namespace Bit.Api.Controllers
} }
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
await _cipherService.SaveAsync(cipher, userId, model.CollectionIds, true); await _cipherService.SaveAsync(cipher, userId, model.CollectionIds, true, false);
var response = new CipherMiniResponseModel(cipher, _globalSettings, false); var response = new CipherMiniResponseModel(cipher, _globalSettings, false);
return response; return response;
@ -188,7 +188,7 @@ namespace Bit.Api.Controllers
// object cannot be a descendant of CipherDetails, so let's clone it. // object cannot be a descendant of CipherDetails, so let's clone it.
var cipherClone = CoreHelpers.CloneObject(model.ToCipher(cipher)); var cipherClone = CoreHelpers.CloneObject(model.ToCipher(cipher));
await _cipherService.SaveAsync(cipherClone, userId, null, true); await _cipherService.SaveAsync(cipherClone, userId, null, true, false);
var response = new CipherMiniResponseModel(cipherClone, _globalSettings, cipher.OrganizationUseTotp); var response = new CipherMiniResponseModel(cipherClone, _globalSettings, cipher.OrganizationUseTotp);
return response; return response;

View File

@ -9,11 +9,14 @@ namespace Bit.Core.Services
{ {
public interface ICipherService public interface ICipherService
{ {
Task SaveAsync(Cipher cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null, bool skipPermissionCheck = false); Task SaveAsync(Cipher cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null,
Task SaveDetailsAsync(CipherDetails cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null, bool skipPermissionCheck = false); bool skipPermissionCheck = false, bool limitCollectionScope = true);
Task SaveDetailsAsync(CipherDetails cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null,
bool skipPermissionCheck = false);
Task CreateAttachmentAsync(Cipher cipher, Stream stream, string fileName, long requestLength, Guid savingUserId, Task CreateAttachmentAsync(Cipher cipher, Stream stream, string fileName, long requestLength, Guid savingUserId,
bool orgAdmin = false); bool orgAdmin = false);
Task CreateAttachmentShareAsync(Cipher cipher, Stream stream, string fileName, long requestLength, string attachmentId, Task CreateAttachmentShareAsync(Cipher cipher, Stream stream, string fileName, long requestLength,
string attachmentId,
Guid organizationShareId); Guid organizationShareId);
Task DeleteAsync(Cipher cipher, Guid deletingUserId, bool orgAdmin = false); Task DeleteAsync(Cipher cipher, Guid deletingUserId, bool orgAdmin = false);
Task DeleteManyAsync(IEnumerable<Guid> cipherIds, Guid deletingUserId); Task DeleteManyAsync(IEnumerable<Guid> cipherIds, Guid deletingUserId);
@ -22,8 +25,10 @@ namespace Bit.Core.Services
Task MoveManyAsync(IEnumerable<Guid> cipherIds, Guid? destinationFolderId, Guid movingUserId); Task MoveManyAsync(IEnumerable<Guid> cipherIds, Guid? destinationFolderId, Guid movingUserId);
Task SaveFolderAsync(Folder folder); Task SaveFolderAsync(Folder folder);
Task DeleteFolderAsync(Folder folder); Task DeleteFolderAsync(Folder folder);
Task ShareAsync(Cipher originalCipher, Cipher cipher, Guid organizationId, IEnumerable<Guid> collectionIds, Guid userId); Task ShareAsync(Cipher originalCipher, Cipher cipher, Guid organizationId, IEnumerable<Guid> collectionIds,
Task ShareManyAsync(IEnumerable<Cipher> ciphers, Guid organizationId, IEnumerable<Guid> collectionIds, Guid sharingUserId); Guid userId);
Task ShareManyAsync(IEnumerable<Cipher> ciphers, Guid organizationId, IEnumerable<Guid> collectionIds,
Guid sharingUserId);
Task SaveCollectionsAsync(Cipher cipher, IEnumerable<Guid> collectionIds, Guid savingUserId, bool orgAdmin); Task SaveCollectionsAsync(Cipher cipher, IEnumerable<Guid> collectionIds, Guid savingUserId, bool orgAdmin);
Task ImportCiphersAsync(List<Folder> folders, List<CipherDetails> ciphers, Task ImportCiphersAsync(List<Folder> folders, List<CipherDetails> ciphers,
IEnumerable<KeyValuePair<int, int>> folderRelationships); IEnumerable<KeyValuePair<int, int>> folderRelationships);

View File

@ -56,7 +56,7 @@ namespace Bit.Core.Services
} }
public async Task SaveAsync(Cipher cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null, public async Task SaveAsync(Cipher cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null,
bool skipPermissionCheck = false) bool skipPermissionCheck = false, bool limitCollectionScope = true)
{ {
if(!skipPermissionCheck && !(await UserCanEditAsync(cipher, savingUserId))) if(!skipPermissionCheck && !(await UserCanEditAsync(cipher, savingUserId)))
{ {
@ -67,8 +67,11 @@ namespace Bit.Core.Services
{ {
if(cipher.OrganizationId.HasValue && collectionIds != null) if(cipher.OrganizationId.HasValue && collectionIds != null)
{ {
// Set user ID to limit scope of collection ids in the create sproc if(limitCollectionScope)
cipher.UserId = savingUserId; {
// Set user ID to limit scope of collection ids in the create sproc
cipher.UserId = savingUserId;
}
await _cipherRepository.CreateAsync(cipher, collectionIds); await _cipherRepository.CreateAsync(cipher, collectionIds);
} }
else else

View File

@ -16,33 +16,46 @@ BEGIN
[Id] UNIQUEIDENTIFIER [Id] UNIQUEIDENTIFIER
) )
INSERT INTO #AvailableCollections IF @UserId IS NULL
SELECT BEGIN
C.[Id] INSERT INTO #AvailableCollections
FROM SELECT
[dbo].[Collection] C [Id]
INNER JOIN FROM
[Organization] O ON O.[Id] = C.[OrganizationId] [dbo].[Collection]
INNER JOIN WHERE
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [Id] = @OrganizationId
LEFT JOIN END
[dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id] ELSE
LEFT JOIN BEGIN
[dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] INSERT INTO #AvailableCollections
LEFT JOIN SELECT
[dbo].[Group] G ON G.[Id] = GU.[GroupId] C.[Id]
LEFT JOIN FROM
[dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] [dbo].[Collection] C
WHERE INNER JOIN
O.[Id] = @OrganizationId [Organization] O ON O.[Id] = C.[OrganizationId]
AND O.[Enabled] = 1 INNER JOIN
AND OU.[Status] = 2 -- Confirmed [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
AND ( LEFT JOIN
OU.[AccessAll] = 1 [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id]
OR CU.[ReadOnly] = 0 LEFT JOIN
OR G.[AccessAll] = 1 [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id]
OR CG.[ReadOnly] = 0 LEFT JOIN
) [dbo].[Group] G ON G.[Id] = GU.[GroupId]
LEFT JOIN
[dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId]
WHERE
O.[Id] = @OrganizationId
AND O.[Enabled] = 1
AND OU.[Status] = 2 -- Confirmed
AND (
OU.[AccessAll] = 1
OR CU.[ReadOnly] = 0
OR G.[AccessAll] = 1
OR CG.[ReadOnly] = 0
)
END
IF (SELECT COUNT(1) FROM #AvailableCollections) < 1 IF (SELECT COUNT(1) FROM #AvailableCollections) < 1
BEGIN BEGIN

View File

@ -255,33 +255,46 @@ BEGIN
[Id] UNIQUEIDENTIFIER [Id] UNIQUEIDENTIFIER
) )
INSERT INTO #AvailableCollections IF @UserId IS NULL
SELECT BEGIN
C.[Id] INSERT INTO #AvailableCollections
FROM SELECT
[dbo].[Collection] C [Id]
INNER JOIN FROM
[Organization] O ON O.[Id] = C.[OrganizationId] [dbo].[Collection]
INNER JOIN WHERE
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [Id] = @OrganizationId
LEFT JOIN END
[dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id] ELSE
LEFT JOIN BEGIN
[dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] INSERT INTO #AvailableCollections
LEFT JOIN SELECT
[dbo].[Group] G ON G.[Id] = GU.[GroupId] C.[Id]
LEFT JOIN FROM
[dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] [dbo].[Collection] C
WHERE INNER JOIN
O.[Id] = @OrganizationId [Organization] O ON O.[Id] = C.[OrganizationId]
AND O.[Enabled] = 1 INNER JOIN
AND OU.[Status] = 2 -- Confirmed [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
AND ( LEFT JOIN
OU.[AccessAll] = 1 [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id]
OR CU.[ReadOnly] = 0 LEFT JOIN
OR G.[AccessAll] = 1 [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id]
OR CG.[ReadOnly] = 0 LEFT JOIN
) [dbo].[Group] G ON G.[Id] = GU.[GroupId]
LEFT JOIN
[dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId]
WHERE
O.[Id] = @OrganizationId
AND O.[Enabled] = 1
AND OU.[Status] = 2 -- Confirmed
AND (
OU.[AccessAll] = 1
OR CU.[ReadOnly] = 0
OR G.[AccessAll] = 1
OR CG.[ReadOnly] = 0
)
END
IF (SELECT COUNT(1) FROM #AvailableCollections) < 1 IF (SELECT COUNT(1) FROM #AvailableCollections) < 1
BEGIN BEGIN