mirror of
https://github.com/bitwarden/server.git
synced 2024-11-22 12:15:36 +01:00
apis for org vault listing
This commit is contained in:
parent
5b76c43fb0
commit
0e5799f7c8
@ -85,6 +85,25 @@ namespace Bit.Api.Controllers
|
||||
return new ListResponseModel<CipherDetailsResponseModel>(responses);
|
||||
}
|
||||
|
||||
[HttpGet("organization-details")]
|
||||
public async Task<ListResponseModel<CipherMiniDetailsResponseModel>> GetOrganizationSubvaults(string organizationId)
|
||||
{
|
||||
var userId = _userService.GetProperUserId(User).Value;
|
||||
var orgIdGuid = new Guid(organizationId);
|
||||
if(!_currentContext.OrganizationAdmin(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var ciphers = await _cipherRepository.GetManyByOrganizationIdAsync(orgIdGuid);
|
||||
|
||||
var subvaultCiphers = await _subvaultCipherRepository.GetManyByOrganizationIdAsync(orgIdGuid);
|
||||
var subvaultCiphersGroupDict = subvaultCiphers.GroupBy(s => s.CipherId).ToDictionary(s => s.Key);
|
||||
|
||||
var responses = ciphers.Select(c => new CipherMiniDetailsResponseModel(c, subvaultCiphersGroupDict));
|
||||
return new ListResponseModel<CipherMiniDetailsResponseModel>(responses);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
[HttpGet("history")]
|
||||
public Task<CipherHistoryResponseModel> Get(DateTime since)
|
||||
@ -116,7 +135,7 @@ namespace Bit.Api.Controllers
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
|
||||
await _cipherService.UpdatePartialAsync(new Guid(id), userId, cipher.FolderId, !cipher.Favorite);
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,9 @@ using System.Linq;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class CipherResponseModel : ResponseModel
|
||||
public class CipherMiniResponseModel : ResponseModel
|
||||
{
|
||||
public CipherResponseModel(CipherDetails cipher, string obj = "cipher")
|
||||
public CipherMiniResponseModel(Cipher cipher, string obj = "cipherMini")
|
||||
: base(obj)
|
||||
{
|
||||
if(cipher == null)
|
||||
@ -20,8 +20,6 @@ namespace Bit.Core.Models.Api
|
||||
Type = cipher.Type;
|
||||
RevisionDate = cipher.RevisionDate;
|
||||
OrganizationId = cipher.OrganizationId?.ToString();
|
||||
FolderId = cipher.FolderId?.ToString();
|
||||
Favorite = cipher.Favorite;
|
||||
|
||||
switch(cipher.Type)
|
||||
{
|
||||
@ -35,13 +33,24 @@ namespace Bit.Core.Models.Api
|
||||
|
||||
public string Id { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public Enums.CipherType Type { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public dynamic Data { get; set; }
|
||||
public DateTime RevisionDate { get; set; }
|
||||
}
|
||||
|
||||
public class CipherResponseModel : CipherMiniResponseModel
|
||||
{
|
||||
public CipherResponseModel(CipherDetails cipher, string obj = "cipher")
|
||||
: base(cipher, obj)
|
||||
{
|
||||
FolderId = cipher.FolderId?.ToString();
|
||||
Favorite = cipher.Favorite;
|
||||
}
|
||||
|
||||
public string FolderId { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
}
|
||||
|
||||
public class CipherDetailsResponseModel : CipherResponseModel
|
||||
{
|
||||
public CipherDetailsResponseModel(CipherDetails cipher,
|
||||
@ -68,6 +77,25 @@ namespace Bit.Core.Models.Api
|
||||
public IEnumerable<Guid> SubvaultIds { get; set; }
|
||||
}
|
||||
|
||||
public class CipherMiniDetailsResponseModel : CipherMiniResponseModel
|
||||
{
|
||||
public CipherMiniDetailsResponseModel(Cipher cipher,
|
||||
IDictionary<Guid, IGrouping<Guid, SubvaultCipher>> subvaultCiphers, string obj = "cipherMiniDetails")
|
||||
: base(cipher, obj)
|
||||
{
|
||||
if(subvaultCiphers.ContainsKey(cipher.Id))
|
||||
{
|
||||
SubvaultIds = subvaultCiphers[cipher.Id].Select(s => s.SubvaultId);
|
||||
}
|
||||
else
|
||||
{
|
||||
SubvaultIds = new Guid[] { };
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Guid> SubvaultIds { get; set; }
|
||||
}
|
||||
|
||||
public class CipherFullDetailsResponseModel : CipherDetailsResponseModel
|
||||
{
|
||||
public CipherFullDetailsResponseModel(CipherFullDetails cipher, IEnumerable<SubvaultCipher> subvaultCiphers)
|
||||
|
@ -12,6 +12,7 @@ namespace Bit.Core.Repositories
|
||||
Task<CipherFullDetails> GetFullDetailsByIdAsync(Guid id, Guid userId);
|
||||
Task<ICollection<CipherDetails>> GetManyByUserIdAsync(Guid userId);
|
||||
Task<ICollection<CipherDetails>> GetManyByUserIdHasSubvaultsAsync(Guid userId);
|
||||
Task<ICollection<Cipher>> GetManyByOrganizationIdAsync(Guid organizationId);
|
||||
Task<ICollection<CipherDetails>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId);
|
||||
Task CreateAsync(CipherDetails cipher);
|
||||
Task ReplaceAsync(CipherDetails cipher);
|
||||
|
@ -8,6 +8,7 @@ namespace Bit.Core.Repositories
|
||||
public interface ISubvaultCipherRepository
|
||||
{
|
||||
Task<ICollection<SubvaultCipher>> GetManyByUserIdAsync(Guid userId);
|
||||
Task<ICollection<SubvaultCipher>> GetManyByOrganizationIdAsync(Guid organizationId);
|
||||
Task<ICollection<SubvaultCipher>> GetManyByUserIdCipherIdAsync(Guid userId, Guid cipherId);
|
||||
Task UpdateSubvaultsAsync(Guid cipherId, Guid userId, IEnumerable<Guid> subvaultIds);
|
||||
}
|
||||
|
@ -76,6 +76,19 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<Cipher>> GetManyByOrganizationIdAsync(Guid organizationId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<Cipher>(
|
||||
$"[{Schema}].[Cipher_ReadByOrganizationId]",
|
||||
new { OrganizationId = organizationId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<CipherDetails>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -33,6 +33,19 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<SubvaultCipher>> GetManyByOrganizationIdAsync(Guid organizationId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<SubvaultCipher>(
|
||||
"[dbo].[SubvaultCipher_ReadByOrganizationId]",
|
||||
new { OrganizationId = organizationId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<SubvaultCipher>> GetManyByUserIdCipherIdAsync(Guid userId, Guid cipherId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -174,5 +174,7 @@
|
||||
<Build Include="dbo\Stored Procedures\OrganizationUserUserDetails_ReadById.sql" />
|
||||
<Build Include="dbo\Stored Procedures\OrganizationUserUserDetails_ReadByOrganizationId.sql" />
|
||||
<Build Include="dbo\User Defined Types\GuidIdArray.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Cipher_ReadByOrganizationId.sql" />
|
||||
<Build Include="dbo\Stored Procedures\SubvaultCipher_ReadByOrganizationId.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,13 @@
|
||||
CREATE PROCEDURE [dbo].[Cipher_ReadByOrganizationId]
|
||||
@OrganizationId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
[dbo].[CipherView]
|
||||
WHERE
|
||||
[OrganizationId] = @OrganizationId
|
||||
END
|
@ -0,0 +1,15 @@
|
||||
CREATE PROCEDURE [dbo].[SubvaultCipher_ReadByOrganizationId]
|
||||
@OrganizationId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
SELECT
|
||||
SC.*
|
||||
FROM
|
||||
[dbo].[SubvaultCipher] SC
|
||||
INNER JOIN
|
||||
[dbo].[Subvault] S ON S.[Id] = SC.[SubvaultId]
|
||||
WHERE
|
||||
S.[OrganizationId] = @OrganizationId
|
||||
END
|
@ -18,6 +18,12 @@ CREATE NONCLUSTERED INDEX [IX_Cipher_UserId_Type]
|
||||
ON [dbo].[Cipher]([UserId] ASC, [Type] ASC);
|
||||
|
||||
|
||||
GO
|
||||
CREATE NONCLUSTERED INDEX [IX_Cipher_OrganizationId_Type]
|
||||
ON [dbo].[Cipher]([OrganizationId] ASC, [Type] ASC)
|
||||
WHERE [OrganizationId] IS NOT NULL;
|
||||
|
||||
|
||||
GO
|
||||
CREATE TRIGGER [dbo].[Cipher_Inserted]
|
||||
ON [dbo].[Cipher] AFTER INSERT
|
||||
|
Loading…
Reference in New Issue
Block a user