1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-06 21:48:12 -05:00

renaming subvault => collection

This commit is contained in:
Kyle Spearrin 2017-04-27 09:19:30 -04:00
parent 2340369d56
commit c6ac82dadd
87 changed files with 493 additions and 493 deletions

View File

@ -17,7 +17,7 @@ namespace Bit.Api.Controllers
{ {
private readonly ICipherRepository _cipherRepository; private readonly ICipherRepository _cipherRepository;
private readonly IFolderRepository _folderRepository; private readonly IFolderRepository _folderRepository;
private readonly ISubvaultCipherRepository _subvaultCipherRepository; private readonly ICollectionCipherRepository _collectionCipherRepository;
private readonly ICipherService _cipherService; private readonly ICipherService _cipherService;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly CurrentContext _currentContext; private readonly CurrentContext _currentContext;
@ -25,14 +25,14 @@ namespace Bit.Api.Controllers
public CiphersController( public CiphersController(
ICipherRepository cipherRepository, ICipherRepository cipherRepository,
IFolderRepository folderRepository, IFolderRepository folderRepository,
ISubvaultCipherRepository subvaultCipherRepository, ICollectionCipherRepository collectionCipherRepository,
ICipherService cipherService, ICipherService cipherService,
IUserService userService, IUserService userService,
CurrentContext currentContext) CurrentContext currentContext)
{ {
_cipherRepository = cipherRepository; _cipherRepository = cipherRepository;
_folderRepository = folderRepository; _folderRepository = folderRepository;
_subvaultCipherRepository = subvaultCipherRepository; _collectionCipherRepository = collectionCipherRepository;
_cipherService = cipherService; _cipherService = cipherService;
_userService = userService; _userService = userService;
_currentContext = currentContext; _currentContext = currentContext;
@ -62,8 +62,8 @@ namespace Bit.Api.Controllers
throw new NotFoundException(); throw new NotFoundException();
} }
var subvaultCiphers = await _subvaultCipherRepository.GetManyByUserIdCipherIdAsync(userId, cipherId); var collectionCiphers = await _collectionCipherRepository.GetManyByUserIdCipherIdAsync(userId, cipherId);
return new CipherFullDetailsResponseModel(cipher, subvaultCiphers); return new CipherFullDetailsResponseModel(cipher, collectionCiphers);
} }
[HttpGet("")] [HttpGet("")]
@ -91,20 +91,20 @@ namespace Bit.Api.Controllers
} }
[HttpGet("details")] [HttpGet("details")]
public async Task<ListResponseModel<CipherDetailsResponseModel>> GetSubvaults() public async Task<ListResponseModel<CipherDetailsResponseModel>> GetCollections()
{ {
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
var ciphers = await _cipherRepository.GetManyByUserIdHasSubvaultsAsync(userId); var ciphers = await _cipherRepository.GetManyByUserIdHasCollectionsAsync(userId);
var subvaultCiphers = await _subvaultCipherRepository.GetManyByUserIdAsync(userId); var collectionCiphers = await _collectionCipherRepository.GetManyByUserIdAsync(userId);
var subvaultCiphersGroupDict = subvaultCiphers.GroupBy(s => s.CipherId).ToDictionary(s => s.Key); var collectionCiphersGroupDict = collectionCiphers.GroupBy(s => s.CipherId).ToDictionary(s => s.Key);
var responses = ciphers.Select(c => new CipherDetailsResponseModel(c, subvaultCiphersGroupDict)); var responses = ciphers.Select(c => new CipherDetailsResponseModel(c, collectionCiphersGroupDict));
return new ListResponseModel<CipherDetailsResponseModel>(responses); return new ListResponseModel<CipherDetailsResponseModel>(responses);
} }
[HttpGet("organization-details")] [HttpGet("organization-details")]
public async Task<ListResponseModel<CipherMiniDetailsResponseModel>> GetOrganizationSubvaults(string organizationId) public async Task<ListResponseModel<CipherMiniDetailsResponseModel>> GetOrganizationCollections(string organizationId)
{ {
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
var orgIdGuid = new Guid(organizationId); var orgIdGuid = new Guid(organizationId);
@ -115,10 +115,10 @@ namespace Bit.Api.Controllers
var ciphers = await _cipherRepository.GetManyByOrganizationIdAsync(orgIdGuid); var ciphers = await _cipherRepository.GetManyByOrganizationIdAsync(orgIdGuid);
var subvaultCiphers = await _subvaultCipherRepository.GetManyByOrganizationIdAsync(orgIdGuid); var collectionCiphers = await _collectionCipherRepository.GetManyByOrganizationIdAsync(orgIdGuid);
var subvaultCiphersGroupDict = subvaultCiphers.GroupBy(s => s.CipherId).ToDictionary(s => s.Key); var collectionCiphersGroupDict = collectionCiphers.GroupBy(s => s.CipherId).ToDictionary(s => s.Key);
var responses = ciphers.Select(c => new CipherMiniDetailsResponseModel(c, subvaultCiphersGroupDict)); var responses = ciphers.Select(c => new CipherMiniDetailsResponseModel(c, collectionCiphersGroupDict));
return new ListResponseModel<CipherMiniDetailsResponseModel>(responses); return new ListResponseModel<CipherMiniDetailsResponseModel>(responses);
} }
@ -179,12 +179,12 @@ namespace Bit.Api.Controllers
} }
await _cipherService.ShareAsync(model.Cipher.ToCipher(cipher), new Guid(model.Cipher.OrganizationId), await _cipherService.ShareAsync(model.Cipher.ToCipher(cipher), new Guid(model.Cipher.OrganizationId),
model.SubvaultIds.Select(s => new Guid(s)), userId); model.CollectionIds.Select(s => new Guid(s)), userId);
} }
[HttpPut("{id}/subvaults")] [HttpPut("{id}/collections")]
[HttpPost("{id}/subvaults")] [HttpPost("{id}/collections")]
public async Task PutSubvaults(string id, [FromBody]CipherSubvaultsRequestModel model) public async Task PutCollections(string id, [FromBody]CipherCollectionsRequestModel model)
{ {
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
var cipher = await _cipherRepository.GetByIdAsync(new Guid(id), userId); var cipher = await _cipherRepository.GetByIdAsync(new Guid(id), userId);
@ -194,12 +194,12 @@ namespace Bit.Api.Controllers
throw new NotFoundException(); throw new NotFoundException();
} }
await _cipherService.SaveSubvaultsAsync(cipher, model.SubvaultIds.Select(s => new Guid(s)), userId, false); await _cipherService.SaveCollectionsAsync(cipher, model.CollectionIds.Select(s => new Guid(s)), userId, false);
} }
[HttpPut("{id}/subvaults-admin")] [HttpPut("{id}/collections-admin")]
[HttpPost("{id}/subvaults-admin")] [HttpPost("{id}/collections-admin")]
public async Task PutSubvaultsAdmin(string id, [FromBody]CipherSubvaultsRequestModel model) public async Task PutCollectionsAdmin(string id, [FromBody]CipherCollectionsRequestModel model)
{ {
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
var cipher = await _cipherRepository.GetByIdAsync(new Guid(id)); var cipher = await _cipherRepository.GetByIdAsync(new Guid(id));
@ -209,7 +209,7 @@ namespace Bit.Api.Controllers
throw new NotFoundException(); throw new NotFoundException();
} }
await _cipherService.SaveSubvaultsAsync(cipher, model.SubvaultIds.Select(s => new Guid(s)), userId, true); await _cipherService.SaveCollectionsAsync(cipher, model.CollectionIds.Select(s => new Guid(s)), userId, true);
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]

View File

@ -18,7 +18,7 @@ namespace Bit.Api.Controllers
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IOrganizationService _organizationService; private readonly IOrganizationService _organizationService;
private readonly ISubvaultRepository _subvaultRepository; private readonly ICollectionRepository _collectionRepository;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly CurrentContext _currentContext; private readonly CurrentContext _currentContext;
@ -26,14 +26,14 @@ namespace Bit.Api.Controllers
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
IOrganizationService organizationService, IOrganizationService organizationService,
ISubvaultRepository subvaultRepository, ICollectionRepository collectionRepository,
IUserService userService, IUserService userService,
CurrentContext currentContext) CurrentContext currentContext)
{ {
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_organizationService = organizationService; _organizationService = organizationService;
_subvaultRepository = subvaultRepository; _collectionRepository = collectionRepository;
_userService = userService; _userService = userService;
_currentContext = currentContext; _currentContext = currentContext;
} }
@ -75,7 +75,7 @@ namespace Bit.Api.Controllers
var userId = _userService.GetProperUserId(User); var userId = _userService.GetProperUserId(User);
var result = await _organizationService.InviteUserAsync(orgGuidId, userId.Value, model.Email, model.Type.Value, var result = await _organizationService.InviteUserAsync(orgGuidId, userId.Value, model.Email, model.Type.Value,
model.AccessAllSubvaults, model.Subvaults?.Select(s => s.ToSubvaultUser())); model.AccessAllCollections, model.Collections?.Select(s => s.ToCollectionUser()));
} }
[HttpPut("{id}/reinvite")] [HttpPut("{id}/reinvite")]
@ -132,7 +132,7 @@ namespace Bit.Api.Controllers
var userId = _userService.GetProperUserId(User); var userId = _userService.GetProperUserId(User);
await _organizationService.SaveUserAsync(model.ToOrganizationUser(organizationUser), userId.Value, await _organizationService.SaveUserAsync(model.ToOrganizationUser(organizationUser), userId.Value,
model.Subvaults?.Select(s => s.ToSubvaultUser())); model.Collections?.Select(s => s.ToCollectionUser()));
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]

View File

@ -11,59 +11,59 @@ using Bit.Core;
namespace Bit.Api.Controllers namespace Bit.Api.Controllers
{ {
[Route("organizations/{orgId}/subvaultUsers")] [Route("organizations/{orgId}/collectionUsers")]
[Authorize("Application")] [Authorize("Application")]
public class SubvaultUsersController : Controller public class CollectionUsersController : Controller
{ {
private readonly ISubvaultRepository _subvaultRepository; private readonly ICollectionRepository _collectionRepository;
private readonly ISubvaultUserRepository _subvaultUserRepository; private readonly ICollectionUserRepository _collectionUserRepository;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly CurrentContext _currentContext; private readonly CurrentContext _currentContext;
public SubvaultUsersController( public CollectionUsersController(
ISubvaultRepository subvaultRepository, ICollectionRepository collectionRepository,
ISubvaultUserRepository subvaultUserRepository, ICollectionUserRepository collectionUserRepository,
IUserService userService, IUserService userService,
CurrentContext currentContext) CurrentContext currentContext)
{ {
_subvaultRepository = subvaultRepository; _collectionRepository = collectionRepository;
_subvaultUserRepository = subvaultUserRepository; _collectionUserRepository = collectionUserRepository;
_userService = userService; _userService = userService;
_currentContext = currentContext; _currentContext = currentContext;
} }
[HttpGet("{subvaultId}")] [HttpGet("{collectionId}")]
public async Task<ListResponseModel<SubvaultUserResponseModel>> GetBySubvault(string orgId, string subvaultId) public async Task<ListResponseModel<CollectionUserResponseModel>> GetByCollection(string orgId, string collectionId)
{ {
var subvaultIdGuid = new Guid(subvaultId); var collectionIdGuid = new Guid(collectionId);
var subvault = await _subvaultRepository.GetByIdAsync(subvaultIdGuid); var collection = await _collectionRepository.GetByIdAsync(collectionIdGuid);
if(subvault == null || !_currentContext.OrganizationAdmin(subvault.OrganizationId)) if(collection == null || !_currentContext.OrganizationAdmin(collection.OrganizationId))
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
var subvaultUsers = await _subvaultUserRepository.GetManyDetailsBySubvaultIdAsync(subvaultIdGuid); var collectionUsers = await _collectionUserRepository.GetManyDetailsByCollectionIdAsync(collectionIdGuid);
var responses = subvaultUsers.Select(s => new SubvaultUserResponseModel(s)); var responses = collectionUsers.Select(s => new CollectionUserResponseModel(s));
return new ListResponseModel<SubvaultUserResponseModel>(responses); return new ListResponseModel<CollectionUserResponseModel>(responses);
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
[HttpPost("{id}/delete")] [HttpPost("{id}/delete")]
public async Task Delete(string orgId, string id) public async Task Delete(string orgId, string id)
{ {
var user = await _subvaultUserRepository.GetByIdAsync(new Guid(id)); var user = await _collectionUserRepository.GetByIdAsync(new Guid(id));
if(user == null) if(user == null)
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
var subvault = await _subvaultRepository.GetByIdAsync(user.SubvaultId); var collection = await _collectionRepository.GetByIdAsync(user.CollectionId);
if(subvault == null || !_currentContext.OrganizationAdmin(subvault.OrganizationId)) if(collection == null || !_currentContext.OrganizationAdmin(collection.OrganizationId))
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
await _subvaultUserRepository.DeleteAsync(user); await _collectionUserRepository.DeleteAsync(user);
} }
} }
} }

View File

@ -11,41 +11,41 @@ using Bit.Core;
namespace Bit.Api.Controllers namespace Bit.Api.Controllers
{ {
[Route("organizations/{orgId}/subvaults")] [Route("organizations/{orgId}/collections")]
[Authorize("Application")] [Authorize("Application")]
public class SubvaultsController : Controller public class CollectionsController : Controller
{ {
private readonly ISubvaultRepository _subvaultRepository; private readonly ICollectionRepository _collectionRepository;
private readonly ISubvaultService _subvaultService; private readonly ICollectionService _collectionService;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly CurrentContext _currentContext; private readonly CurrentContext _currentContext;
public SubvaultsController( public CollectionsController(
ISubvaultRepository subvaultRepository, ICollectionRepository collectionRepository,
ISubvaultService subvaultService, ICollectionService collectionService,
IUserService userService, IUserService userService,
CurrentContext currentContext) CurrentContext currentContext)
{ {
_subvaultRepository = subvaultRepository; _collectionRepository = collectionRepository;
_subvaultService = subvaultService; _collectionService = collectionService;
_userService = userService; _userService = userService;
_currentContext = currentContext; _currentContext = currentContext;
} }
[HttpGet("{id}")] [HttpGet("{id}")]
public async Task<SubvaultResponseModel> Get(string orgId, string id) public async Task<CollectionResponseModel> Get(string orgId, string id)
{ {
var subvault = await _subvaultRepository.GetByIdAsync(new Guid(id)); var collection = await _collectionRepository.GetByIdAsync(new Guid(id));
if(subvault == null || !_currentContext.OrganizationAdmin(subvault.OrganizationId)) if(collection == null || !_currentContext.OrganizationAdmin(collection.OrganizationId))
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
return new SubvaultResponseModel(subvault); return new CollectionResponseModel(collection);
} }
[HttpGet("")] [HttpGet("")]
public async Task<ListResponseModel<SubvaultResponseModel>> Get(string orgId) public async Task<ListResponseModel<CollectionResponseModel>> Get(string orgId)
{ {
var orgIdGuid = new Guid(orgId); var orgIdGuid = new Guid(orgId);
if(!_currentContext.OrganizationAdmin(orgIdGuid)) if(!_currentContext.OrganizationAdmin(orgIdGuid))
@ -53,21 +53,21 @@ namespace Bit.Api.Controllers
throw new NotFoundException(); throw new NotFoundException();
} }
var subvaults = await _subvaultRepository.GetManyByOrganizationIdAsync(orgIdGuid); var collections = await _collectionRepository.GetManyByOrganizationIdAsync(orgIdGuid);
var responses = subvaults.Select(s => new SubvaultResponseModel(s)); var responses = collections.Select(s => new CollectionResponseModel(s));
return new ListResponseModel<SubvaultResponseModel>(responses); return new ListResponseModel<CollectionResponseModel>(responses);
} }
[HttpGet("~/subvaults")] [HttpGet("~/collections")]
public async Task<ListResponseModel<SubvaultResponseModel>> GetUser() public async Task<ListResponseModel<CollectionResponseModel>> GetUser()
{ {
var subvaults = await _subvaultRepository.GetManyByUserIdAsync(_userService.GetProperUserId(User).Value); var collections = await _collectionRepository.GetManyByUserIdAsync(_userService.GetProperUserId(User).Value);
var responses = subvaults.Select(s => new SubvaultResponseModel(s)); var responses = collections.Select(s => new CollectionResponseModel(s));
return new ListResponseModel<SubvaultResponseModel>(responses); return new ListResponseModel<CollectionResponseModel>(responses);
} }
[HttpPost("")] [HttpPost("")]
public async Task<SubvaultResponseModel> Post(string orgId, [FromBody]SubvaultRequestModel model) public async Task<CollectionResponseModel> Post(string orgId, [FromBody]CollectionRequestModel model)
{ {
var orgIdGuid = new Guid(orgId); var orgIdGuid = new Guid(orgId);
if(!_currentContext.OrganizationAdmin(orgIdGuid)) if(!_currentContext.OrganizationAdmin(orgIdGuid))
@ -75,36 +75,36 @@ namespace Bit.Api.Controllers
throw new NotFoundException(); throw new NotFoundException();
} }
var subvault = model.ToSubvault(orgIdGuid); var collection = model.ToCollection(orgIdGuid);
await _subvaultService.SaveAsync(subvault); await _collectionService.SaveAsync(collection);
return new SubvaultResponseModel(subvault); return new CollectionResponseModel(collection);
} }
[HttpPut("{id}")] [HttpPut("{id}")]
[HttpPost("{id}")] [HttpPost("{id}")]
public async Task<SubvaultResponseModel> Put(string orgId, string id, [FromBody]SubvaultRequestModel model) public async Task<CollectionResponseModel> Put(string orgId, string id, [FromBody]CollectionRequestModel model)
{ {
var subvault = await _subvaultRepository.GetByIdAsync(new Guid(id)); var collection = await _collectionRepository.GetByIdAsync(new Guid(id));
if(subvault == null || !_currentContext.OrganizationAdmin(subvault.OrganizationId)) if(collection == null || !_currentContext.OrganizationAdmin(collection.OrganizationId))
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
await _subvaultService.SaveAsync(model.ToSubvault(subvault)); await _collectionService.SaveAsync(model.ToCollection(collection));
return new SubvaultResponseModel(subvault); return new CollectionResponseModel(collection);
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
[HttpPost("{id}/delete")] [HttpPost("{id}/delete")]
public async Task Delete(string orgId, string id) public async Task Delete(string orgId, string id)
{ {
var subvault = await _subvaultRepository.GetByIdAsync(new Guid(id)); var collection = await _collectionRepository.GetByIdAsync(new Guid(id));
if(subvault == null || !_currentContext.OrganizationAdmin(subvault.OrganizationId)) if(collection == null || !_currentContext.OrganizationAdmin(collection.OrganizationId))
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
await _subvaultRepository.DeleteAsync(subvault); await _collectionRepository.DeleteAsync(collection);
} }
} }
} }

View File

@ -64,7 +64,7 @@ namespace Bit.Core.Models.Api
public class CipherShareRequestModel : IValidatableObject public class CipherShareRequestModel : IValidatableObject
{ {
[Required] [Required]
public IEnumerable<string> SubvaultIds { get; set; } public IEnumerable<string> CollectionIds { get; set; }
[Required] [Required]
public CipherRequestModel Cipher { get; set; } public CipherRequestModel Cipher { get; set; }
@ -76,17 +76,17 @@ namespace Bit.Core.Models.Api
new string[] { nameof(Cipher.OrganizationId) }); new string[] { nameof(Cipher.OrganizationId) });
} }
if(!SubvaultIds?.Any() ?? false) if(!CollectionIds?.Any() ?? false)
{ {
yield return new ValidationResult("You must select at least one subvault.", yield return new ValidationResult("You must select at least one collection.",
new string[] { nameof(SubvaultIds) }); new string[] { nameof(CollectionIds) });
} }
} }
} }
public class CipherSubvaultsRequestModel public class CipherCollectionsRequestModel
{ {
[Required] [Required]
public IEnumerable<string> SubvaultIds { get; set; } public IEnumerable<string> CollectionIds { get; set; }
} }
} }

View File

@ -12,8 +12,8 @@ namespace Bit.Core.Models.Api
public string Email { get; set; } public string Email { get; set; }
[Required] [Required]
public Enums.OrganizationUserType? Type { get; set; } public Enums.OrganizationUserType? Type { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
public IEnumerable<OrganizationUserSubvaultRequestModel> Subvaults { get; set; } public IEnumerable<OrganizationUserCollectionRequestModel> Collections { get; set; }
} }
public class OrganizationUserAcceptRequestModel public class OrganizationUserAcceptRequestModel
@ -32,32 +32,32 @@ namespace Bit.Core.Models.Api
{ {
[Required] [Required]
public Enums.OrganizationUserType? Type { get; set; } public Enums.OrganizationUserType? Type { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
public IEnumerable<OrganizationUserSubvaultRequestModel> Subvaults { get; set; } public IEnumerable<OrganizationUserCollectionRequestModel> Collections { get; set; }
public OrganizationUser ToOrganizationUser(OrganizationUser existingUser) public OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
{ {
existingUser.Type = Type.Value; existingUser.Type = Type.Value;
existingUser.AccessAllSubvaults = AccessAllSubvaults; existingUser.AccessAllCollections = AccessAllCollections;
return existingUser; return existingUser;
} }
} }
public class OrganizationUserSubvaultRequestModel public class OrganizationUserCollectionRequestModel
{ {
[Required] [Required]
public string SubvaultId { get; set; } public string CollectionId { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
public SubvaultUser ToSubvaultUser() public CollectionUser ToCollectionUser()
{ {
var subvault = new SubvaultUser var collection = new CollectionUser
{ {
ReadOnly = ReadOnly, ReadOnly = ReadOnly,
SubvaultId = new Guid(SubvaultId) CollectionId = new Guid(CollectionId)
}; };
return subvault; return collection;
} }
} }
} }

View File

@ -6,25 +6,25 @@ using Newtonsoft.Json;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
public class SubvaultRequestModel public class CollectionRequestModel
{ {
[Required] [Required]
[EncryptedString] [EncryptedString]
[StringLength(300)] [StringLength(300)]
public string Name { get; set; } public string Name { get; set; }
public Subvault ToSubvault(Guid orgId) public Collection ToCollection(Guid orgId)
{ {
return ToSubvault(new Subvault return ToCollection(new Collection
{ {
OrganizationId = orgId OrganizationId = orgId
}); });
} }
public Subvault ToSubvault(Subvault existingSubvault) public Collection ToCollection(Collection existingCollection)
{ {
existingSubvault.Name = Name; existingCollection.Name = Name;
return existingSubvault; return existingCollection;
} }
} }
} }

View File

@ -5,29 +5,29 @@ using System.Linq;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
public class SubvaultUserSubvaultRequestModel public class CollectionUserCollectionRequestModel
{ {
public string UserId { get; set; } public string UserId { get; set; }
public IEnumerable<Subvault> Subvaults { get; set; } public IEnumerable<Collection> Collections { get; set; }
public IEnumerable<SubvaultUser> ToSubvaultUsers() public IEnumerable<CollectionUser> ToCollectionUsers()
{ {
return Subvaults.Select(s => new SubvaultUser return Collections.Select(s => new CollectionUser
{ {
OrganizationUserId = new Guid(UserId), OrganizationUserId = new Guid(UserId),
SubvaultId = new Guid(s.SubvaultId), CollectionId = new Guid(s.CollectionId),
ReadOnly = s.ReadOnly ReadOnly = s.ReadOnly
}); });
} }
public class Subvault public class Collection
{ {
public string SubvaultId { get; set; } public string CollectionId { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
} }
} }
public class SubvaultUserUserRequestModel public class CollectionUserUserRequestModel
{ {
public string UserId { get; set; } public string UserId { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }

View File

@ -74,52 +74,52 @@ namespace Bit.Core.Models.Api
public class CipherDetailsResponseModel : CipherResponseModel public class CipherDetailsResponseModel : CipherResponseModel
{ {
public CipherDetailsResponseModel(CipherDetails cipher, public CipherDetailsResponseModel(CipherDetails cipher,
IDictionary<Guid, IGrouping<Guid, SubvaultCipher>> subvaultCiphers, string obj = "cipherDetails") IDictionary<Guid, IGrouping<Guid, CollectionCipher>> collectionCiphers, string obj = "cipherDetails")
: base(cipher, obj) : base(cipher, obj)
{ {
if(subvaultCiphers.ContainsKey(cipher.Id)) if(collectionCiphers.ContainsKey(cipher.Id))
{ {
SubvaultIds = subvaultCiphers[cipher.Id].Select(s => s.SubvaultId); CollectionIds = collectionCiphers[cipher.Id].Select(s => s.CollectionId);
} }
else else
{ {
SubvaultIds = new Guid[] { }; CollectionIds = new Guid[] { };
} }
} }
public CipherDetailsResponseModel(CipherDetails cipher, IEnumerable<SubvaultCipher> subvaultCiphers, public CipherDetailsResponseModel(CipherDetails cipher, IEnumerable<CollectionCipher> collectionCiphers,
string obj = "cipherDetails") string obj = "cipherDetails")
: base(cipher, obj) : base(cipher, obj)
{ {
SubvaultIds = subvaultCiphers.Select(s => s.SubvaultId); CollectionIds = collectionCiphers.Select(s => s.CollectionId);
} }
public IEnumerable<Guid> SubvaultIds { get; set; } public IEnumerable<Guid> CollectionIds { get; set; }
} }
public class CipherMiniDetailsResponseModel : CipherMiniResponseModel public class CipherMiniDetailsResponseModel : CipherMiniResponseModel
{ {
public CipherMiniDetailsResponseModel(Cipher cipher, public CipherMiniDetailsResponseModel(Cipher cipher,
IDictionary<Guid, IGrouping<Guid, SubvaultCipher>> subvaultCiphers, string obj = "cipherMiniDetails") IDictionary<Guid, IGrouping<Guid, CollectionCipher>> collectionCiphers, string obj = "cipherMiniDetails")
: base(cipher, obj) : base(cipher, obj)
{ {
if(subvaultCiphers.ContainsKey(cipher.Id)) if(collectionCiphers.ContainsKey(cipher.Id))
{ {
SubvaultIds = subvaultCiphers[cipher.Id].Select(s => s.SubvaultId); CollectionIds = collectionCiphers[cipher.Id].Select(s => s.CollectionId);
} }
else else
{ {
SubvaultIds = new Guid[] { }; CollectionIds = new Guid[] { };
} }
} }
public IEnumerable<Guid> SubvaultIds { get; set; } public IEnumerable<Guid> CollectionIds { get; set; }
} }
public class CipherFullDetailsResponseModel : CipherDetailsResponseModel public class CipherFullDetailsResponseModel : CipherDetailsResponseModel
{ {
public CipherFullDetailsResponseModel(CipherFullDetails cipher, IEnumerable<SubvaultCipher> subvaultCiphers) public CipherFullDetailsResponseModel(CipherFullDetails cipher, IEnumerable<CollectionCipher> collectionCiphers)
: base(cipher, subvaultCiphers, "cipherFullDetails") : base(cipher, collectionCiphers, "cipherFullDetails")
{ {
Edit = cipher.Edit; Edit = cipher.Edit;
} }

View File

@ -22,7 +22,7 @@ namespace Bit.Core.Models.Api
Email = organizationUser.Email; Email = organizationUser.Email;
Type = organizationUser.Type; Type = organizationUser.Type;
Status = organizationUser.Status; Status = organizationUser.Status;
AccessAllSubvaults = organizationUser.AccessAllSubvaults; AccessAllCollections = organizationUser.AccessAllCollections;
} }
public string Id { get; set; } public string Id { get; set; }
@ -31,19 +31,19 @@ namespace Bit.Core.Models.Api
public string Email { get; set; } public string Email { get; set; }
public OrganizationUserType Type { get; set; } public OrganizationUserType Type { get; set; }
public OrganizationUserStatusType Status { get; set; } public OrganizationUserStatusType Status { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
} }
public class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel public class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel
{ {
public OrganizationUserDetailsResponseModel(OrganizationUserUserDetails organizationUser, public OrganizationUserDetailsResponseModel(OrganizationUserUserDetails organizationUser,
IEnumerable<SubvaultUserSubvaultDetails> subvaults) IEnumerable<CollectionUserCollectionDetails> collections)
: base(organizationUser, "organizationUserDetails") : base(organizationUser, "organizationUserDetails")
{ {
Subvaults = new ListResponseModel<OrganizationUserSubvaultResponseModel>( Collections = new ListResponseModel<OrganizationUserCollectionResponseModel>(
subvaults.Select(s => new OrganizationUserSubvaultResponseModel(s))); collections.Select(s => new OrganizationUserCollectionResponseModel(s)));
} }
public ListResponseModel<OrganizationUserSubvaultResponseModel> Subvaults { get; set; } public ListResponseModel<OrganizationUserCollectionResponseModel> Collections { get; set; }
} }
} }

View File

@ -3,10 +3,10 @@ using Bit.Core.Models.Data;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
public class OrganizationUserSubvaultResponseModel : ResponseModel public class OrganizationUserCollectionResponseModel : ResponseModel
{ {
public OrganizationUserSubvaultResponseModel(SubvaultUserSubvaultDetails details, public OrganizationUserCollectionResponseModel(CollectionUserCollectionDetails details,
string obj = "organizationUserSubvault") string obj = "organizationUserCollection")
: base(obj) : base(obj)
{ {
if(details == null) if(details == null)
@ -16,13 +16,13 @@ namespace Bit.Core.Models.Api
Id = details.Id.ToString(); Id = details.Id.ToString();
Name = details.Name; Name = details.Name;
SubvaultId = details.SubvaultId.ToString(); CollectionId = details.CollectionId.ToString();
ReadOnly = details.ReadOnly; ReadOnly = details.ReadOnly;
} }
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string SubvaultId { get; set; } public string CollectionId { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
} }
} }

View File

@ -3,19 +3,19 @@ using Bit.Core.Models.Table;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
public class SubvaultResponseModel : ResponseModel public class CollectionResponseModel : ResponseModel
{ {
public SubvaultResponseModel(Subvault subvault) public CollectionResponseModel(Collection collection)
: base("subvault") : base("collection")
{ {
if(subvault == null) if(collection == null)
{ {
throw new ArgumentNullException(nameof(subvault)); throw new ArgumentNullException(nameof(collection));
} }
Id = subvault.Id.ToString(); Id = collection.Id.ToString();
OrganizationId = subvault.OrganizationId.ToString(); OrganizationId = collection.OrganizationId.ToString();
Name = subvault.Name; Name = collection.Name;
} }
public string Id { get; set; } public string Id { get; set; }

View File

@ -5,31 +5,31 @@ using Bit.Core.Enums;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
public class SubvaultUserResponseModel : ResponseModel public class CollectionUserResponseModel : ResponseModel
{ {
public SubvaultUserResponseModel(SubvaultUserUserDetails subvaultUser) public CollectionUserResponseModel(CollectionUserUserDetails collectionUser)
: base("subvaultUser") : base("collectionUser")
{ {
if(subvaultUser == null) if(collectionUser == null)
{ {
throw new ArgumentNullException(nameof(subvaultUser)); throw new ArgumentNullException(nameof(collectionUser));
} }
Id = subvaultUser.Id?.ToString(); Id = collectionUser.Id?.ToString();
OrganizationUserId = subvaultUser.OrganizationUserId.ToString(); OrganizationUserId = collectionUser.OrganizationUserId.ToString();
SubvaultId = subvaultUser.SubvaultId?.ToString(); CollectionId = collectionUser.CollectionId?.ToString();
AccessAllSubvaults = subvaultUser.AccessAllSubvaults; AccessAllCollections = collectionUser.AccessAllCollections;
Name = subvaultUser.Name; Name = collectionUser.Name;
Email = subvaultUser.Email; Email = collectionUser.Email;
Type = subvaultUser.Type; Type = collectionUser.Type;
Status = subvaultUser.Status; Status = collectionUser.Status;
ReadOnly = subvaultUser.ReadOnly; ReadOnly = collectionUser.ReadOnly;
} }
public string Id { get; set; } public string Id { get; set; }
public string OrganizationUserId { get; set; } public string OrganizationUserId { get; set; }
public string SubvaultId { get; set; } public string CollectionId { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Email { get; set; } public string Email { get; set; }
public OrganizationUserType Type { get; set; } public OrganizationUserType Type { get; set; }

View File

@ -11,6 +11,6 @@ namespace Bit.Core.Models.Data
public string Email { get; set; } public string Email { get; set; }
public Enums.OrganizationUserStatusType Status { get; set; } public Enums.OrganizationUserStatusType Status { get; set; }
public Enums.OrganizationUserType Type { get; set; } public Enums.OrganizationUserType Type { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
} }
} }

View File

@ -2,12 +2,12 @@
namespace Bit.Core.Models.Data namespace Bit.Core.Models.Data
{ {
public class SubvaultUserSubvaultDetails public class CollectionUserCollectionDetails
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid OrganizationUserId { get; set; } public Guid OrganizationUserId { get; set; }
public string Name { get; set; } public string Name { get; set; }
public Guid SubvaultId { get; set; } public Guid CollectionId { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
} }
} }

View File

@ -2,12 +2,12 @@
namespace Bit.Core.Models.Data namespace Bit.Core.Models.Data
{ {
public class SubvaultUserUserDetails public class CollectionUserUserDetails
{ {
public Guid? Id { get; set; } public Guid? Id { get; set; }
public Guid OrganizationUserId { get; set; } public Guid OrganizationUserId { get; set; }
public Guid? SubvaultId { get; set; } public Guid? CollectionId { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Email { get; set; } public string Email { get; set; }
public Enums.OrganizationUserStatusType Status { get; set; } public Enums.OrganizationUserStatusType Status { get; set; }

View File

@ -13,7 +13,7 @@ namespace Bit.Core.Models.StaticStore
public short? MaxAdditionalSeats { get; set; } public short? MaxAdditionalSeats { get; set; }
public decimal BasePrice { get; set; } public decimal BasePrice { get; set; }
public decimal SeatPrice { get; set; } public decimal SeatPrice { get; set; }
public short? MaxSubvaults { get; set; } public short? MaxCollections { get; set; }
public int UpgradeSortOrder { get; set; } public int UpgradeSortOrder { get; set; }
public bool Disabled { get; set; } public bool Disabled { get; set; }
public int? TrialPeriodDays { get; set; } public int? TrialPeriodDays { get; set; }

View File

@ -13,7 +13,7 @@ namespace Bit.Core.Models.Table
public string Plan { get; set; } public string Plan { get; set; }
public PlanType PlanType { get; set; } public PlanType PlanType { get; set; }
public short? Seats { get; set; } public short? Seats { get; set; }
public short? MaxSubvaults { get; set; } public short? MaxCollections { get; set; }
public string StripeCustomerId { get; set; } public string StripeCustomerId { get; set; }
public string StripeSubscriptionId { get; set; } public string StripeSubscriptionId { get; set; }
public bool Enabled { get; set; } = true; public bool Enabled { get; set; } = true;

View File

@ -13,7 +13,7 @@ namespace Bit.Core.Models.Table
public string Key { get; set; } public string Key { get; set; }
public OrganizationUserStatusType Status { get; set; } public OrganizationUserStatusType Status { get; set; }
public OrganizationUserType Type { get; set; } public OrganizationUserType Type { get; set; }
public bool AccessAllSubvaults { get; set; } public bool AccessAllCollections { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;

View File

@ -3,7 +3,7 @@ using Bit.Core.Utilities;
namespace Bit.Core.Models.Table namespace Bit.Core.Models.Table
{ {
public class Subvault : IDataObject<Guid> public class Collection : IDataObject<Guid>
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid OrganizationId { get; set; } public Guid OrganizationId { get; set; }

View File

@ -2,9 +2,9 @@
namespace Bit.Core.Models.Table namespace Bit.Core.Models.Table
{ {
public class SubvaultCipher public class CollectionCipher
{ {
public Guid SubvaultId { get; set; } public Guid CollectionId { get; set; }
public Guid CipherId { get; set; } public Guid CipherId { get; set; }
} }
} }

View File

@ -3,10 +3,10 @@ using Bit.Core.Utilities;
namespace Bit.Core.Models.Table namespace Bit.Core.Models.Table
{ {
public class SubvaultUser : IDataObject<Guid> public class CollectionUser : IDataObject<Guid>
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid SubvaultId { get; set; } public Guid CollectionId { get; set; }
public Guid OrganizationUserId { get; set; } public Guid OrganizationUserId { get; set; }
public bool ReadOnly { get; set; } public bool ReadOnly { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;

View File

@ -11,13 +11,13 @@ namespace Bit.Core.Repositories
Task<CipherDetails> GetByIdAsync(Guid id, Guid userId); Task<CipherDetails> GetByIdAsync(Guid id, Guid userId);
Task<CipherFullDetails> GetFullDetailsByIdAsync(Guid id, Guid userId); Task<CipherFullDetails> GetFullDetailsByIdAsync(Guid id, Guid userId);
Task<ICollection<CipherDetails>> GetManyByUserIdAsync(Guid userId); Task<ICollection<CipherDetails>> GetManyByUserIdAsync(Guid userId);
Task<ICollection<CipherDetails>> GetManyByUserIdHasSubvaultsAsync(Guid userId); Task<ICollection<CipherDetails>> GetManyByUserIdHasCollectionsAsync(Guid userId);
Task<ICollection<Cipher>> GetManyByOrganizationIdAsync(Guid organizationId); Task<ICollection<Cipher>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<CipherDetails>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId); Task<ICollection<CipherDetails>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId);
Task CreateAsync(CipherDetails cipher); Task CreateAsync(CipherDetails cipher);
Task ReplaceAsync(CipherDetails cipher); Task ReplaceAsync(CipherDetails cipher);
Task UpsertAsync(CipherDetails cipher); Task UpsertAsync(CipherDetails cipher);
Task ReplaceAsync(Cipher obj, IEnumerable<Guid> subvaultIds); Task ReplaceAsync(Cipher obj, IEnumerable<Guid> collectionIds);
Task UpdatePartialAsync(Guid id, Guid userId, Guid? folderId, bool favorite); Task UpdatePartialAsync(Guid id, Guid userId, Guid? folderId, bool favorite);
Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders); Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders);
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders); Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders);

View File

@ -15,7 +15,7 @@ namespace Bit.Core.Repositories
Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type); Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type);
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, string email); Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, string email);
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId); Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId);
Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>> GetDetailsByIdAsync(Guid id); Task<Tuple<OrganizationUserUserDetails, ICollection<CollectionUserCollectionDetails>>> GetDetailsByIdAsync(Guid id);
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId); Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId);
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId, Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
OrganizationUserStatusType? status = null); OrganizationUserStatusType? status = null);

View File

@ -5,12 +5,12 @@ using System.Collections.Generic;
namespace Bit.Core.Repositories namespace Bit.Core.Repositories
{ {
public interface ISubvaultCipherRepository public interface ICollectionCipherRepository
{ {
Task<ICollection<SubvaultCipher>> GetManyByUserIdAsync(Guid userId); Task<ICollection<CollectionCipher>> GetManyByUserIdAsync(Guid userId);
Task<ICollection<SubvaultCipher>> GetManyByOrganizationIdAsync(Guid organizationId); Task<ICollection<CollectionCipher>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<SubvaultCipher>> GetManyByUserIdCipherIdAsync(Guid userId, Guid cipherId); Task<ICollection<CollectionCipher>> GetManyByUserIdCipherIdAsync(Guid userId, Guid cipherId);
Task UpdateSubvaultsAsync(Guid cipherId, Guid userId, IEnumerable<Guid> subvaultIds); Task UpdateCollectionsAsync(Guid cipherId, Guid userId, IEnumerable<Guid> collectionIds);
Task UpdateSubvaultsForAdminAsync(Guid cipherId, Guid organizationId, IEnumerable<Guid> subvaultIds); Task UpdateCollectionsForAdminAsync(Guid cipherId, Guid organizationId, IEnumerable<Guid> collectionIds);
} }
} }

View File

@ -5,11 +5,11 @@ using System.Collections.Generic;
namespace Bit.Core.Repositories namespace Bit.Core.Repositories
{ {
public interface ISubvaultRepository : IRepository<Subvault, Guid> public interface ICollectionRepository : IRepository<Collection, Guid>
{ {
Task<int> GetCountByOrganizationIdAsync(Guid organizationId); Task<int> GetCountByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Subvault>> GetManyByOrganizationIdAsync(Guid organizationId); Task<ICollection<Collection>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Subvault>> GetManyByUserIdAsync(Guid userId); Task<ICollection<Collection>> GetManyByUserIdAsync(Guid userId);
} }
} }

View File

@ -6,11 +6,11 @@ using Bit.Core.Models.Data;
namespace Bit.Core.Repositories namespace Bit.Core.Repositories
{ {
public interface ISubvaultUserRepository : IRepository<SubvaultUser, Guid> public interface ICollectionUserRepository : IRepository<CollectionUser, Guid>
{ {
Task<ICollection<SubvaultUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId); Task<ICollection<CollectionUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId);
Task<ICollection<SubvaultUserSubvaultDetails>> GetManyDetailsByUserIdAsync(Guid userId); Task<ICollection<CollectionUserCollectionDetails>> GetManyDetailsByUserIdAsync(Guid userId);
Task<ICollection<SubvaultUserUserDetails>> GetManyDetailsBySubvaultIdAsync(Guid subvaultId); Task<ICollection<CollectionUserUserDetails>> GetManyDetailsByCollectionIdAsync(Guid collectionId);
Task<bool> GetCanEditByUserIdCipherIdAsync(Guid userId, Guid cipherId); Task<bool> GetCanEditByUserIdCipherIdAsync(Guid userId, Guid cipherId);
} }
} }

View File

@ -62,12 +62,12 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<CipherDetails>> GetManyByUserIdHasSubvaultsAsync(Guid userId) public async Task<ICollection<CipherDetails>> GetManyByUserIdHasCollectionsAsync(Guid userId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<CipherDetails>( var results = await connection.QueryAsync<CipherDetails>(
$"[{Schema}].[CipherDetails_ReadByUserIdHasSubvault]", $"[{Schema}].[CipherDetails_ReadByUserIdHasCollection]",
new { UserId = userId }, new { UserId = userId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -142,16 +142,16 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task ReplaceAsync(Cipher obj, IEnumerable<Guid> subvaultIds) public async Task ReplaceAsync(Cipher obj, IEnumerable<Guid> collectionIds)
{ {
var objWithSubvaults = JsonConvert.DeserializeObject<CipherWithSubvaults>(JsonConvert.SerializeObject(obj)); var objWithCollections = JsonConvert.DeserializeObject<CipherWithCollections>(JsonConvert.SerializeObject(obj));
objWithSubvaults.SubvaultIds = subvaultIds.ToGuidIdArrayTVP(); objWithCollections.CollectionIds = collectionIds.ToGuidIdArrayTVP();
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.ExecuteAsync( var results = await connection.ExecuteAsync(
$"[{Schema}].[Cipher_UpdateWithSubvaults]", $"[{Schema}].[Cipher_UpdateWithCollections]",
objWithSubvaults, objWithCollections,
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
} }
} }
@ -419,9 +419,9 @@ namespace Bit.Core.Repositories.SqlServer
return foldersTable; return foldersTable;
} }
public class CipherWithSubvaults : Cipher public class CipherWithCollections : Cipher
{ {
public DataTable SubvaultIds { get; set; } public DataTable CollectionIds { get; set; }
} }
} }
} }

View File

@ -100,7 +100,7 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>> GetDetailsByIdAsync(Guid id) public async Task<Tuple<OrganizationUserUserDetails, ICollection<CollectionUserCollectionDetails>>> GetDetailsByIdAsync(Guid id)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
@ -110,8 +110,8 @@ namespace Bit.Core.Repositories.SqlServer
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
var user = (await results.ReadAsync<OrganizationUserUserDetails>()).SingleOrDefault(); var user = (await results.ReadAsync<OrganizationUserUserDetails>()).SingleOrDefault();
var subvaults = (await results.ReadAsync<SubvaultUserSubvaultDetails>()).ToList(); var collections = (await results.ReadAsync<CollectionUserCollectionDetails>()).ToList();
return new Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>(user, subvaults); return new Tuple<OrganizationUserUserDetails, ICollection<CollectionUserCollectionDetails>>(user, collections);
} }
} }

View File

@ -10,22 +10,22 @@ using Bit.Core.Utilities;
namespace Bit.Core.Repositories.SqlServer namespace Bit.Core.Repositories.SqlServer
{ {
public class SubvaultCipherRepository : BaseRepository, ISubvaultCipherRepository public class CollectionCipherRepository : BaseRepository, ICollectionCipherRepository
{ {
public SubvaultCipherRepository(GlobalSettings globalSettings) public CollectionCipherRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString)
{ } { }
public SubvaultCipherRepository(string connectionString) public CollectionCipherRepository(string connectionString)
: base(connectionString) : base(connectionString)
{ } { }
public async Task<ICollection<SubvaultCipher>> GetManyByUserIdAsync(Guid userId) public async Task<ICollection<CollectionCipher>> GetManyByUserIdAsync(Guid userId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<SubvaultCipher>( var results = await connection.QueryAsync<CollectionCipher>(
"[dbo].[SubvaultCipher_ReadByUserId]", "[dbo].[CollectionCipher_ReadByUserId]",
new { UserId = userId }, new { UserId = userId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -33,12 +33,12 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<SubvaultCipher>> GetManyByOrganizationIdAsync(Guid organizationId) public async Task<ICollection<CollectionCipher>> GetManyByOrganizationIdAsync(Guid organizationId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<SubvaultCipher>( var results = await connection.QueryAsync<CollectionCipher>(
"[dbo].[SubvaultCipher_ReadByOrganizationId]", "[dbo].[CollectionCipher_ReadByOrganizationId]",
new { OrganizationId = organizationId }, new { OrganizationId = organizationId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -46,12 +46,12 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<SubvaultCipher>> GetManyByUserIdCipherIdAsync(Guid userId, Guid cipherId) public async Task<ICollection<CollectionCipher>> GetManyByUserIdCipherIdAsync(Guid userId, Guid cipherId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<SubvaultCipher>( var results = await connection.QueryAsync<CollectionCipher>(
"[dbo].[SubvaultCipher_ReadByUserIdCipherId]", "[dbo].[CollectionCipher_ReadByUserIdCipherId]",
new { UserId = userId, CipherId = cipherId }, new { UserId = userId, CipherId = cipherId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -59,24 +59,24 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task UpdateSubvaultsAsync(Guid cipherId, Guid userId, IEnumerable<Guid> subvaultIds) public async Task UpdateCollectionsAsync(Guid cipherId, Guid userId, IEnumerable<Guid> collectionIds)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.ExecuteAsync( var results = await connection.ExecuteAsync(
"[dbo].[SubvaultCipher_UpdateSubvaults]", "[dbo].[CollectionCipher_UpdateCollections]",
new { CipherId = cipherId, UserId = userId, SubvaultIds = subvaultIds.ToGuidIdArrayTVP() }, new { CipherId = cipherId, UserId = userId, CollectionIds = collectionIds.ToGuidIdArrayTVP() },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
} }
} }
public async Task UpdateSubvaultsForAdminAsync(Guid cipherId, Guid organizationId, IEnumerable<Guid> subvaultIds) public async Task UpdateCollectionsForAdminAsync(Guid cipherId, Guid organizationId, IEnumerable<Guid> collectionIds)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.ExecuteAsync( var results = await connection.ExecuteAsync(
"[dbo].[SubvaultCipher_UpdateSubvaultsAdmin]", "[dbo].[CollectionCipher_UpdateCollectionsAdmin]",
new { CipherId = cipherId, OrganizationId = organizationId, SubvaultIds = subvaultIds.ToGuidIdArrayTVP() }, new { CipherId = cipherId, OrganizationId = organizationId, CollectionIds = collectionIds.ToGuidIdArrayTVP() },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
} }
} }

View File

@ -9,13 +9,13 @@ using System.Linq;
namespace Bit.Core.Repositories.SqlServer namespace Bit.Core.Repositories.SqlServer
{ {
public class SubvaultRepository : Repository<Subvault, Guid>, ISubvaultRepository public class CollectionRepository : Repository<Collection, Guid>, ICollectionRepository
{ {
public SubvaultRepository(GlobalSettings globalSettings) public CollectionRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString)
{ } { }
public SubvaultRepository(string connectionString) public CollectionRepository(string connectionString)
: base(connectionString) : base(connectionString)
{ } { }
@ -24,7 +24,7 @@ namespace Bit.Core.Repositories.SqlServer
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.ExecuteScalarAsync<int>( var results = await connection.ExecuteScalarAsync<int>(
"[dbo].[Subvault_ReadCountByOrganizationId]", "[dbo].[Collection_ReadCountByOrganizationId]",
new { OrganizationId = organizationId }, new { OrganizationId = organizationId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -32,11 +32,11 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<Subvault>> GetManyByOrganizationIdAsync(Guid organizationId) public async Task<ICollection<Collection>> GetManyByOrganizationIdAsync(Guid organizationId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<Subvault>( var results = await connection.QueryAsync<Collection>(
$"[{Schema}].[{Table}_ReadByOrganizationId]", $"[{Schema}].[{Table}_ReadByOrganizationId]",
new { OrganizationId = organizationId }, new { OrganizationId = organizationId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -45,11 +45,11 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<Subvault>> GetManyByUserIdAsync(Guid userId) public async Task<ICollection<Collection>> GetManyByUserIdAsync(Guid userId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<Subvault>( var results = await connection.QueryAsync<Collection>(
$"[{Schema}].[{Table}_ReadByUserId]", $"[{Schema}].[{Table}_ReadByUserId]",
new { UserId = userId }, new { UserId = userId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);

View File

@ -10,21 +10,21 @@ using Bit.Core.Models.Data;
namespace Bit.Core.Repositories.SqlServer namespace Bit.Core.Repositories.SqlServer
{ {
public class SubvaultUserRepository : Repository<SubvaultUser, Guid>, ISubvaultUserRepository public class CollectionUserRepository : Repository<CollectionUser, Guid>, ICollectionUserRepository
{ {
public SubvaultUserRepository(GlobalSettings globalSettings) public CollectionUserRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString)
{ } { }
public SubvaultUserRepository(string connectionString) public CollectionUserRepository(string connectionString)
: base(connectionString) : base(connectionString)
{ } { }
public async Task<ICollection<SubvaultUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId) public async Task<ICollection<CollectionUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<SubvaultUser>( var results = await connection.QueryAsync<CollectionUser>(
$"[{Schema}].[{Table}_ReadByOrganizationUserId]", $"[{Schema}].[{Table}_ReadByOrganizationUserId]",
new { OrganizationUserId = orgUserId }, new { OrganizationUserId = orgUserId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -33,12 +33,12 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<SubvaultUserSubvaultDetails>> GetManyDetailsByUserIdAsync(Guid userId) public async Task<ICollection<CollectionUserCollectionDetails>> GetManyDetailsByUserIdAsync(Guid userId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<SubvaultUserSubvaultDetails>( var results = await connection.QueryAsync<CollectionUserCollectionDetails>(
$"[{Schema}].[SubvaultUserSubvaultDetails_ReadByUserId]", $"[{Schema}].[CollectionUserCollectionDetails_ReadByUserId]",
new { UserId = userId }, new { UserId = userId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
@ -46,13 +46,13 @@ namespace Bit.Core.Repositories.SqlServer
} }
} }
public async Task<ICollection<SubvaultUserUserDetails>> GetManyDetailsBySubvaultIdAsync(Guid subvaultId) public async Task<ICollection<CollectionUserUserDetails>> GetManyDetailsByCollectionIdAsync(Guid collectionId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var results = await connection.QueryAsync<SubvaultUserUserDetails>( var results = await connection.QueryAsync<CollectionUserUserDetails>(
$"[{Schema}].[SubvaultUserUserDetails_ReadBySubvaultId]", $"[{Schema}].[CollectionUserUserDetails_ReadByCollectionId]",
new { SubvaultId = subvaultId }, new { CollectionId = collectionId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);
return results.ToList(); return results.ToList();
@ -64,7 +64,7 @@ namespace Bit.Core.Repositories.SqlServer
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))
{ {
var result = await connection.QueryFirstOrDefaultAsync<bool>( var result = await connection.QueryFirstOrDefaultAsync<bool>(
$"[{Schema}].[SubvaultUser_ReadCanEditByCipherIdUserId]", $"[{Schema}].[CollectionUser_ReadCanEditByCipherIdUserId]",
new { UserId = userId, CipherId = cipherId }, new { UserId = userId, CipherId = cipherId },
commandType: CommandType.StoredProcedure); commandType: CommandType.StoredProcedure);

View File

@ -15,10 +15,10 @@ namespace Bit.Core
services.AddSingleton<IGrantRepository, SqlServerRepos.GrantRepository>(); services.AddSingleton<IGrantRepository, SqlServerRepos.GrantRepository>();
services.AddSingleton<IOrganizationRepository, SqlServerRepos.OrganizationRepository>(); services.AddSingleton<IOrganizationRepository, SqlServerRepos.OrganizationRepository>();
services.AddSingleton<IOrganizationUserRepository, SqlServerRepos.OrganizationUserRepository>(); services.AddSingleton<IOrganizationUserRepository, SqlServerRepos.OrganizationUserRepository>();
services.AddSingleton<ISubvaultRepository, SqlServerRepos.SubvaultRepository>(); services.AddSingleton<ICollectionRepository, SqlServerRepos.CollectionRepository>();
services.AddSingleton<ISubvaultUserRepository, SqlServerRepos.SubvaultUserRepository>(); services.AddSingleton<ICollectionUserRepository, SqlServerRepos.CollectionUserRepository>();
services.AddSingleton<IFolderRepository, SqlServerRepos.FolderRepository>(); services.AddSingleton<IFolderRepository, SqlServerRepos.FolderRepository>();
services.AddSingleton<ISubvaultCipherRepository, SqlServerRepos.SubvaultCipherRepository>(); services.AddSingleton<ICollectionCipherRepository, SqlServerRepos.CollectionCipherRepository>();
} }
public static void AddBaseServices(this IServiceCollection services) public static void AddBaseServices(this IServiceCollection services)
@ -27,7 +27,7 @@ namespace Bit.Core
services.AddScoped<IUserService, UserService>(); services.AddScoped<IUserService, UserService>();
services.AddScoped<IDeviceService, DeviceService>(); services.AddScoped<IDeviceService, DeviceService>();
services.AddScoped<IOrganizationService, OrganizationService>(); services.AddScoped<IOrganizationService, OrganizationService>();
services.AddScoped<ISubvaultService, SubvaultService>(); services.AddScoped<ICollectionService, CollectionService>();
} }
public static void AddDefaultServices(this IServiceCollection services) public static void AddDefaultServices(this IServiceCollection services)

View File

@ -12,8 +12,8 @@ namespace Bit.Core.Services
Task DeleteAsync(Cipher cipher, Guid deletingUserId, bool orgAdmin = false); Task DeleteAsync(Cipher cipher, Guid deletingUserId, bool orgAdmin = false);
Task SaveFolderAsync(Folder folder); Task SaveFolderAsync(Folder folder);
Task DeleteFolderAsync(Folder folder); Task DeleteFolderAsync(Folder folder);
Task ShareAsync(Cipher cipher, Guid organizationId, IEnumerable<Guid> subvaultIds, Guid userId); Task ShareAsync(Cipher cipher, Guid organizationId, IEnumerable<Guid> collectionIds, Guid userId);
Task SaveSubvaultsAsync(Cipher cipher, IEnumerable<Guid> subvaultIds, 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

@ -21,11 +21,11 @@ namespace Bit.Core.Services
Task EnableAsync(Guid organizationId); Task EnableAsync(Guid organizationId);
Task UpdateAsync(Organization organization, bool updateBilling = false); Task UpdateAsync(Organization organization, bool updateBilling = false);
Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email, Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email,
Enums.OrganizationUserType type, bool accessAllSubvaults, IEnumerable<SubvaultUser> subvaults); Enums.OrganizationUserType type, bool accessAllCollections, IEnumerable<CollectionUser> collections);
Task ResendInviteAsync(Guid organizationId, Guid invitingUserId, Guid organizationUserId); Task ResendInviteAsync(Guid organizationId, Guid invitingUserId, Guid organizationUserId);
Task<OrganizationUser> AcceptUserAsync(Guid organizationUserId, User user, string token); Task<OrganizationUser> AcceptUserAsync(Guid organizationUserId, User user, string token);
Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key, Guid confirmingUserId); Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key, Guid confirmingUserId);
Task SaveUserAsync(OrganizationUser user, Guid savingUserId, IEnumerable<SubvaultUser> subvaults); Task SaveUserAsync(OrganizationUser user, Guid savingUserId, IEnumerable<CollectionUser> collections);
Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid deletingUserId); Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid deletingUserId);
Task DeleteUserAsync(Guid organizationId, Guid userId); Task DeleteUserAsync(Guid organizationId, Guid userId);
} }

View File

@ -3,8 +3,8 @@ using Bit.Core.Models.Table;
namespace Bit.Core.Services namespace Bit.Core.Services
{ {
public interface ISubvaultService public interface ICollectionService
{ {
Task SaveAsync(Subvault subvault); Task SaveAsync(Collection collection);
} }
} }

View File

@ -16,8 +16,8 @@ namespace Bit.Core.Services
private readonly IUserRepository _userRepository; private readonly IUserRepository _userRepository;
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ISubvaultUserRepository _subvaultUserRepository; private readonly ICollectionUserRepository _collectionUserRepository;
private readonly ISubvaultCipherRepository _subvaultCipherRepository; private readonly ICollectionCipherRepository _collectionCipherRepository;
private readonly IPushService _pushService; private readonly IPushService _pushService;
public CipherService( public CipherService(
@ -26,8 +26,8 @@ namespace Bit.Core.Services
IUserRepository userRepository, IUserRepository userRepository,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
ISubvaultUserRepository subvaultUserRepository, ICollectionUserRepository collectionUserRepository,
ISubvaultCipherRepository subvaultCipherRepository, ICollectionCipherRepository collectionCipherRepository,
IPushService pushService) IPushService pushService)
{ {
_cipherRepository = cipherRepository; _cipherRepository = cipherRepository;
@ -35,8 +35,8 @@ namespace Bit.Core.Services
_userRepository = userRepository; _userRepository = userRepository;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_subvaultUserRepository = subvaultUserRepository; _collectionUserRepository = collectionUserRepository;
_subvaultCipherRepository = subvaultCipherRepository; _collectionCipherRepository = collectionCipherRepository;
_pushService = pushService; _pushService = pushService;
} }
@ -105,7 +105,7 @@ namespace Bit.Core.Services
await _pushService.PushSyncFolderDeleteAsync(folder); await _pushService.PushSyncFolderDeleteAsync(folder);
} }
public async Task ShareAsync(Cipher cipher, Guid organizationId, IEnumerable<Guid> subvaultIds, Guid sharingUserId) public async Task ShareAsync(Cipher cipher, Guid organizationId, IEnumerable<Guid> collectionIds, Guid sharingUserId)
{ {
if(cipher.Id == default(Guid)) if(cipher.Id == default(Guid))
{ {
@ -122,17 +122,17 @@ namespace Bit.Core.Services
throw new NotFoundException(); throw new NotFoundException();
} }
// Sproc will not save this UserId on the cipher. It is used limit scope of the subvaultIds. // Sproc will not save this UserId on the cipher. It is used limit scope of the collectionIds.
cipher.UserId = sharingUserId; cipher.UserId = sharingUserId;
cipher.OrganizationId = organizationId; cipher.OrganizationId = organizationId;
cipher.RevisionDate = DateTime.UtcNow; cipher.RevisionDate = DateTime.UtcNow;
await _cipherRepository.ReplaceAsync(cipher, subvaultIds); await _cipherRepository.ReplaceAsync(cipher, collectionIds);
// push // push
await _pushService.PushSyncCipherUpdateAsync(cipher); await _pushService.PushSyncCipherUpdateAsync(cipher);
} }
public async Task SaveSubvaultsAsync(Cipher cipher, IEnumerable<Guid> subvaultIds, Guid savingUserId, bool orgAdmin) public async Task SaveCollectionsAsync(Cipher cipher, IEnumerable<Guid> collectionIds, Guid savingUserId, bool orgAdmin)
{ {
if(cipher.Id == default(Guid)) if(cipher.Id == default(Guid))
{ {
@ -144,15 +144,15 @@ namespace Bit.Core.Services
throw new BadRequestException("Cipher must belong to an organization."); throw new BadRequestException("Cipher must belong to an organization.");
} }
// The sprocs will validate that all subvaults belong to this org/user and that they have proper write permissions. // The sprocs will validate that all collections belong to this org/user and that they have proper write permissions.
if(orgAdmin) if(orgAdmin)
{ {
await _subvaultCipherRepository.UpdateSubvaultsForAdminAsync(cipher.Id, cipher.OrganizationId.Value, await _collectionCipherRepository.UpdateCollectionsForAdminAsync(cipher.Id, cipher.OrganizationId.Value,
subvaultIds); collectionIds);
} }
else else
{ {
await _subvaultCipherRepository.UpdateSubvaultsAsync(cipher.Id, savingUserId, subvaultIds); await _collectionCipherRepository.UpdateCollectionsAsync(cipher.Id, savingUserId, collectionIds);
} }
// push // push
@ -213,7 +213,7 @@ namespace Bit.Core.Services
return true; return true;
} }
return await _subvaultUserRepository.GetCanEditByUserIdCipherIdAsync(userId, cipher.Id); return await _collectionUserRepository.GetCanEditByUserIdCipherIdAsync(userId, cipher.Id);
} }
} }
} }

View File

@ -18,8 +18,8 @@ namespace Bit.Core.Services
{ {
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ISubvaultRepository _subvaultRepository; private readonly ICollectionRepository _collectionRepository;
private readonly ISubvaultUserRepository _subvaultUserRepository; private readonly ICollectionUserRepository _collectionUserRepository;
private readonly IUserRepository _userRepository; private readonly IUserRepository _userRepository;
private readonly IDataProtector _dataProtector; private readonly IDataProtector _dataProtector;
private readonly IMailService _mailService; private readonly IMailService _mailService;
@ -28,8 +28,8 @@ namespace Bit.Core.Services
public OrganizationService( public OrganizationService(
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
ISubvaultRepository subvaultRepository, ICollectionRepository collectionRepository,
ISubvaultUserRepository subvaultUserRepository, ICollectionUserRepository collectionUserRepository,
IUserRepository userRepository, IUserRepository userRepository,
IDataProtectionProvider dataProtectionProvider, IDataProtectionProvider dataProtectionProvider,
IMailService mailService, IMailService mailService,
@ -37,8 +37,8 @@ namespace Bit.Core.Services
{ {
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_subvaultRepository = subvaultRepository; _collectionRepository = collectionRepository;
_subvaultUserRepository = subvaultUserRepository; _collectionUserRepository = collectionUserRepository;
_userRepository = userRepository; _userRepository = userRepository;
_dataProtector = dataProtectionProvider.CreateProtector("OrganizationServiceDataProtector"); _dataProtector = dataProtectionProvider.CreateProtector("OrganizationServiceDataProtector");
_mailService = mailService; _mailService = mailService;
@ -269,15 +269,15 @@ namespace Bit.Core.Services
} }
} }
if(newPlan.MaxSubvaults.HasValue && if(newPlan.MaxCollections.HasValue &&
(!organization.MaxSubvaults.HasValue || organization.MaxSubvaults.Value > newPlan.MaxSubvaults.Value)) (!organization.MaxCollections.HasValue || organization.MaxCollections.Value > newPlan.MaxCollections.Value))
{ {
var subvaultCount = await _subvaultRepository.GetCountByOrganizationIdAsync(organization.Id); var collectionCount = await _collectionRepository.GetCountByOrganizationIdAsync(organization.Id);
if(subvaultCount > newPlan.MaxSubvaults.Value) if(collectionCount > newPlan.MaxCollections.Value)
{ {
throw new BadRequestException($"Your organization currently has {subvaultCount} subvaults. " + throw new BadRequestException($"Your organization currently has {collectionCount} collections. " +
$"Your new plan allows for a maximum of ({newPlan.MaxSubvaults.Value}) subvaults. " + $"Your new plan allows for a maximum of ({newPlan.MaxCollections.Value}) collections. " +
"Remove some subvaults."); "Remove some collections.");
} }
} }
@ -551,7 +551,7 @@ namespace Bit.Core.Services
BusinessName = signup.BusinessName, BusinessName = signup.BusinessName,
PlanType = plan.Type, PlanType = plan.Type,
Seats = (short)(plan.BaseSeats + signup.AdditionalSeats), Seats = (short)(plan.BaseSeats + signup.AdditionalSeats),
MaxSubvaults = plan.MaxSubvaults, MaxCollections = plan.MaxCollections,
Plan = plan.Name, Plan = plan.Name,
StripeCustomerId = customer?.Id, StripeCustomerId = customer?.Id,
StripeSubscriptionId = subscription?.Id, StripeSubscriptionId = subscription?.Id,
@ -570,7 +570,7 @@ namespace Bit.Core.Services
Key = signup.OwnerKey, Key = signup.OwnerKey,
Type = OrganizationUserType.Owner, Type = OrganizationUserType.Owner,
Status = OrganizationUserStatusType.Confirmed, Status = OrganizationUserStatusType.Confirmed,
AccessAllSubvaults = true, AccessAllCollections = true,
CreationDate = DateTime.UtcNow, CreationDate = DateTime.UtcNow,
RevisionDate = DateTime.UtcNow RevisionDate = DateTime.UtcNow
}; };
@ -672,7 +672,7 @@ namespace Bit.Core.Services
} }
public async Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email, public async Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email,
OrganizationUserType type, bool accessAllSubvaults, IEnumerable<SubvaultUser> subvaults) OrganizationUserType type, bool accessAllCollections, IEnumerable<CollectionUser> collections)
{ {
var organization = await _organizationRepository.GetByIdAsync(organizationId); var organization = await _organizationRepository.GetByIdAsync(organizationId);
if(organization == null) if(organization == null)
@ -705,15 +705,15 @@ namespace Bit.Core.Services
Key = null, Key = null,
Type = type, Type = type,
Status = OrganizationUserStatusType.Invited, Status = OrganizationUserStatusType.Invited,
AccessAllSubvaults = accessAllSubvaults, AccessAllCollections = accessAllCollections,
CreationDate = DateTime.UtcNow, CreationDate = DateTime.UtcNow,
RevisionDate = DateTime.UtcNow RevisionDate = DateTime.UtcNow
}; };
await _organizationUserRepository.CreateAsync(orgUser); await _organizationUserRepository.CreateAsync(orgUser);
if(!orgUser.AccessAllSubvaults && subvaults.Any()) if(!orgUser.AccessAllCollections && collections.Any())
{ {
await SaveUserSubvaultsAsync(orgUser, subvaults, true); await SaveUserCollectionsAsync(orgUser, collections, true);
} }
await SendInviteAsync(orgUser); await SendInviteAsync(orgUser);
@ -820,7 +820,7 @@ namespace Bit.Core.Services
return orgUser; return orgUser;
} }
public async Task SaveUserAsync(OrganizationUser user, Guid savingUserId, IEnumerable<SubvaultUser> subvaults) public async Task SaveUserAsync(OrganizationUser user, Guid savingUserId, IEnumerable<CollectionUser> collections)
{ {
if(user.Id.Equals(default(Guid))) if(user.Id.Equals(default(Guid)))
{ {
@ -835,12 +835,12 @@ namespace Bit.Core.Services
await _organizationUserRepository.ReplaceAsync(user); await _organizationUserRepository.ReplaceAsync(user);
if(user.AccessAllSubvaults) if(user.AccessAllCollections)
{ {
// We don't need any subvaults if we're flagged to have all access. // We don't need any collections if we're flagged to have all access.
subvaults = new List<SubvaultUser>(); collections = new List<CollectionUser>();
} }
await SaveUserSubvaultsAsync(user, subvaults, false); await SaveUserCollectionsAsync(user, collections, false);
} }
public async Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid deletingUserId) public async Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid deletingUserId)
@ -889,38 +889,38 @@ namespace Bit.Core.Services
return owners.Where(o => o.Status == Enums.OrganizationUserStatusType.Confirmed); return owners.Where(o => o.Status == Enums.OrganizationUserStatusType.Confirmed);
} }
private async Task SaveUserSubvaultsAsync(OrganizationUser user, IEnumerable<SubvaultUser> subvaults, bool newUser) private async Task SaveUserCollectionsAsync(OrganizationUser user, IEnumerable<CollectionUser> collections, bool newUser)
{ {
if(subvaults == null) if(collections == null)
{ {
subvaults = new List<SubvaultUser>(); collections = new List<CollectionUser>();
} }
var orgSubvaults = await _subvaultRepository.GetManyByOrganizationIdAsync(user.OrganizationId); var orgCollections = await _collectionRepository.GetManyByOrganizationIdAsync(user.OrganizationId);
var currentUserSubvaults = newUser ? null : await _subvaultUserRepository.GetManyByOrganizationUserIdAsync(user.Id); var currentUserCollections = newUser ? null : await _collectionUserRepository.GetManyByOrganizationUserIdAsync(user.Id);
// Let's make sure all these belong to this user and organization. // Let's make sure all these belong to this user and organization.
var filteredSubvaults = subvaults.Where(s => orgSubvaults.Any(os => os.Id == s.SubvaultId)); var filteredCollections = collections.Where(s => orgCollections.Any(os => os.Id == s.CollectionId));
foreach(var subvault in filteredSubvaults) foreach(var collection in filteredCollections)
{ {
var existingSubvaultUser = currentUserSubvaults?.FirstOrDefault(cs => cs.SubvaultId == subvault.SubvaultId); var existingCollectionUser = currentUserCollections?.FirstOrDefault(cs => cs.CollectionId == collection.CollectionId);
if(existingSubvaultUser != null) if(existingCollectionUser != null)
{ {
subvault.Id = existingSubvaultUser.Id; collection.Id = existingCollectionUser.Id;
subvault.CreationDate = existingSubvaultUser.CreationDate; collection.CreationDate = existingCollectionUser.CreationDate;
} }
subvault.OrganizationUserId = user.Id; collection.OrganizationUserId = user.Id;
await _subvaultUserRepository.UpsertAsync(subvault); await _collectionUserRepository.UpsertAsync(collection);
} }
if(!newUser) if(!newUser)
{ {
var subvaultsToDelete = currentUserSubvaults.Where(cs => var collectionsToDelete = currentUserCollections.Where(cs =>
!filteredSubvaults.Any(s => s.SubvaultId == cs.SubvaultId)); !filteredCollections.Any(s => s.CollectionId == cs.CollectionId));
foreach(var subvault in subvaultsToDelete) foreach(var collection in collectionsToDelete)
{ {
await _subvaultUserRepository.DeleteAsync(subvault); await _collectionUserRepository.DeleteAsync(collection);
} }
} }
} }

View File

@ -6,56 +6,56 @@ using Bit.Core.Repositories;
namespace Bit.Core.Services namespace Bit.Core.Services
{ {
public class SubvaultService : ISubvaultService public class CollectionService : ICollectionService
{ {
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ISubvaultRepository _subvaultRepository; private readonly ICollectionRepository _collectionRepository;
private readonly ISubvaultUserRepository _subvaultUserRepository; private readonly ICollectionUserRepository _collectionUserRepository;
private readonly IUserRepository _userRepository; private readonly IUserRepository _userRepository;
private readonly IMailService _mailService; private readonly IMailService _mailService;
public SubvaultService( public CollectionService(
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
ISubvaultRepository subvaultRepository, ICollectionRepository collectionRepository,
ISubvaultUserRepository subvaultUserRepository, ICollectionUserRepository collectionUserRepository,
IUserRepository userRepository, IUserRepository userRepository,
IMailService mailService) IMailService mailService)
{ {
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_subvaultRepository = subvaultRepository; _collectionRepository = collectionRepository;
_subvaultUserRepository = subvaultUserRepository; _collectionUserRepository = collectionUserRepository;
_userRepository = userRepository; _userRepository = userRepository;
_mailService = mailService; _mailService = mailService;
} }
public async Task SaveAsync(Subvault subvault) public async Task SaveAsync(Collection collection)
{ {
if(subvault.Id == default(Guid)) if(collection.Id == default(Guid))
{ {
var org = await _organizationRepository.GetByIdAsync(subvault.OrganizationId); var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
if(org == null) if(org == null)
{ {
throw new BadRequestException("Org not found"); throw new BadRequestException("Org not found");
} }
if(org.MaxSubvaults.HasValue) if(org.MaxCollections.HasValue)
{ {
var subvaultCount = await _subvaultRepository.GetCountByOrganizationIdAsync(org.Id); var collectionCount = await _collectionRepository.GetCountByOrganizationIdAsync(org.Id);
if(org.MaxSubvaults.Value <= subvaultCount) if(org.MaxCollections.Value <= collectionCount)
{ {
throw new BadRequestException("You have reached the maximum number of subvaults " + throw new BadRequestException("You have reached the maximum number of collections " +
$"({org.MaxSubvaults.Value}) for this organization."); $"({org.MaxCollections.Value}) for this organization.");
} }
} }
await _subvaultRepository.CreateAsync(subvault); await _collectionRepository.CreateAsync(collection);
} }
else else
{ {
await _subvaultRepository.ReplaceAsync(subvault); await _collectionRepository.ReplaceAsync(collection);
} }
} }
} }

View File

@ -96,7 +96,7 @@ namespace Bit.Core.Utilities
Type = PlanType.Free, Type = PlanType.Free,
BaseSeats = 2, BaseSeats = 2,
CanBuyAdditionalSeats = false, CanBuyAdditionalSeats = false,
MaxSubvaults = 2, MaxCollections = 2,
Name = "Free", Name = "Free",
UpgradeSortOrder = -1 // Always the lowest plan, cannot be upgraded to UpgradeSortOrder = -1 // Always the lowest plan, cannot be upgraded to
}, },

View File

@ -5,7 +5,7 @@ BEGIN
;WITH [CTE] AS( ;WITH [CTE] AS(
SELECT SELECT
CASE WHEN OU.[AccessAllSubvaults] = 1 OR SU.[ReadOnly] = 0 THEN 1 ELSE 0 END [CanEdit] CASE WHEN OU.[AccessAllCollections] = 1 OR SU.[ReadOnly] = 0 THEN 1 ELSE 0 END [CanEdit]
FROM FROM
[dbo].[Cipher] C [dbo].[Cipher] C
INNER JOIN INNER JOIN
@ -13,14 +13,14 @@ BEGIN
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.[Id] = @CipherId C.[Id] = @CipherId
AND OU.[Status] = 2 -- 2 = Confirmed AND OU.[Status] = 2 -- 2 = Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
) )
SELECT SELECT
@CanEdit = CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END @CanEdit = CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END

View File

@ -14,9 +14,9 @@ BEGIN
LEFT JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.Id = @Id C.Id = @Id
AND ( AND (
@ -25,7 +25,7 @@ BEGIN
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[Status] = 2 -- 2 = Confirmed AND OU.[Status] = 2 -- 2 = Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
) )
) )
END END

View File

@ -14,9 +14,9 @@ BEGIN
LEFT JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.[Type] = @Type C.[Type] = @Type
AND ( AND (
@ -25,7 +25,7 @@ BEGIN
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[Status] = 2 -- 2 = Confirmed AND OU.[Status] = 2 -- 2 = Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
) )
) )
END END

View File

@ -13,15 +13,15 @@ BEGIN
LEFT JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.[UserId] = @UserId C.[UserId] = @UserId
OR ( OR (
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[Status] = 2 -- 2 = Confirmed AND OU.[Status] = 2 -- 2 = Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
) )
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[CipherDetails_ReadByUserIdHasSubvault] CREATE PROCEDURE [dbo].[CipherDetails_ReadByUserIdHasCollection]
@UserId UNIQUEIDENTIFIER @UserId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -13,11 +13,11 @@ BEGIN
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[Status] = 2 -- 2 = Confirmed OU.[Status] = 2 -- 2 = Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
END END

View File

@ -18,9 +18,9 @@ BEGIN
LEFT JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.Id = @Id C.Id = @Id
AND ( AND (
@ -29,7 +29,7 @@ BEGIN
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[Status] = 2 -- 2 = Confirmed AND OU.[Status] = 2 -- 2 = Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
) )
) )
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Cipher_UpdateWithSubvaults] CREATE PROCEDURE [dbo].[Cipher_UpdateWithCollections]
@Id UNIQUEIDENTIFIER, @Id UNIQUEIDENTIFIER,
@UserId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER,
@ -8,7 +8,7 @@
@Folders NVARCHAR(MAX), @Folders NVARCHAR(MAX),
@CreationDate DATETIME2(7), @CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7), @RevisionDate DATETIME2(7),
@SubvaultIds AS [dbo].[GuidIdArray] READONLY @CollectionIds AS [dbo].[GuidIdArray] READONLY
AS AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
@ -24,35 +24,35 @@ BEGIN
WHERE WHERE
[Id] = @Id [Id] = @Id
;WITH [AvailableSubvaultsCTE] AS( ;WITH [AvailableCollectionsCTE] AS(
SELECT SELECT
S.[Id] S.[Id]
FROM FROM
[dbo].[Subvault] S [dbo].[Collection] S
INNER JOIN INNER JOIN
[Organization] O ON O.[Id] = S.[OrganizationId] [Organization] O ON O.[Id] = S.[OrganizationId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON OU.[AccessAllCollections] = 0 AND SU.[CollectionId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
O.[Id] = @OrganizationId O.[Id] = @OrganizationId
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND OU.[Status] = 2 -- Confirmed AND OU.[Status] = 2 -- Confirmed
AND (OU.[AccessAllSubvaults] = 1 OR SU.[ReadOnly] = 0) AND (OU.[AccessAllCollections] = 1 OR SU.[ReadOnly] = 0)
) )
INSERT INTO [dbo].[SubvaultCipher] INSERT INTO [dbo].[CollectionCipher]
( (
[SubvaultId], [CollectionId],
[CipherId] [CipherId]
) )
SELECT SELECT
[Id], [Id],
@Id @Id
FROM FROM
@SubvaultIds @CollectionIds
WHERE WHERE
[Id] IN (SELECT [Id] FROM [AvailableSubvaultsCTE]) [Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE])
IF @OrganizationId IS NOT NULL IF @OrganizationId IS NOT NULL
BEGIN BEGIN

View File

@ -18,14 +18,14 @@ BEGIN
LEFT JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id] [dbo].[CollectionCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllCollections] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON SU.[CollectionId] = SC.[CollectionId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.[UserId] = @UserId C.[UserId] = @UserId
OR ( OR (
C.[UserId] IS NULL C.[UserId] IS NULL
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
) )
AND C.[Folders] IS NOT NULL AND C.[Folders] IS NOT NULL
AND JSON_VALUE(C.[Folders], @UserIdPath) = @Id AND JSON_VALUE(C.[Folders], @UserIdPath) = @Id

View File

@ -14,7 +14,7 @@ BEGIN
SELECT SELECT
* *
FROM FROM
[dbo].[SubvaultUserSubvaultDetailsView] [dbo].[CollectionUserCollectionDetailsView]
WHERE WHERE
[OrganizationUserId] = @Id [OrganizationUserId] = @Id
END END

View File

@ -6,7 +6,7 @@
@Key VARCHAR(MAX), @Key VARCHAR(MAX),
@Status TINYINT, @Status TINYINT,
@Type TINYINT, @Type TINYINT,
@AccessAllSubvaults BIT, @AccessAllCollections BIT,
@CreationDate DATETIME2(7), @CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7) @RevisionDate DATETIME2(7)
AS AS
@ -22,7 +22,7 @@ BEGIN
[Key], [Key],
[Status], [Status],
[Type], [Type],
[AccessAllSubvaults], [AccessAllCollections],
[CreationDate], [CreationDate],
[RevisionDate] [RevisionDate]
) )
@ -35,7 +35,7 @@ BEGIN
@Key, @Key,
@Status, @Status,
@Type, @Type,
@AccessAllSubvaults, @AccessAllCollections,
@CreationDate, @CreationDate,
@RevisionDate @RevisionDate
) )

View File

@ -6,7 +6,7 @@ BEGIN
DELETE DELETE
FROM FROM
[dbo].[SubvaultUser] [dbo].[CollectionUser]
WHERE WHERE
[OrganizationUserId] = @Id [OrganizationUserId] = @Id

View File

@ -6,7 +6,7 @@
@Key VARCHAR(MAX), @Key VARCHAR(MAX),
@Status TINYINT, @Status TINYINT,
@Type TINYINT, @Type TINYINT,
@AccessAllSubvaults BIT, @AccessAllCollections BIT,
@CreationDate DATETIME2(7), @CreationDate DATETIME2(7),
@RevisionDate DATETIME2(7) @RevisionDate DATETIME2(7)
AS AS
@ -22,7 +22,7 @@ BEGIN
[Key] = @Key, [Key] = @Key,
[Status] = @Status, [Status] = @Status,
[Type] = @Type, [Type] = @Type,
[AccessAllSubvaults] = @AccessAllSubvaults, [AccessAllCollections] = @AccessAllCollections,
[CreationDate] = @CreationDate, [CreationDate] = @CreationDate,
[RevisionDate] = @RevisionDate [RevisionDate] = @RevisionDate
WHERE WHERE

View File

@ -6,7 +6,7 @@
@Plan NVARCHAR(20), @Plan NVARCHAR(20),
@PlanType TINYINT, @PlanType TINYINT,
@Seats SMALLINT, @Seats SMALLINT,
@MaxSubvaults SMALLINT, @MaxCollections SMALLINT,
@StripeCustomerId VARCHAR(50), @StripeCustomerId VARCHAR(50),
@StripeSubscriptionId VARCHAR(50), @StripeSubscriptionId VARCHAR(50),
@Enabled BIT, @Enabled BIT,
@ -25,7 +25,7 @@ BEGIN
[Plan], [Plan],
[PlanType], [PlanType],
[Seats], [Seats],
[MaxSubvaults], [MaxCollections],
[StripeCustomerId], [StripeCustomerId],
[StripeSubscriptionId], [StripeSubscriptionId],
[Enabled], [Enabled],
@ -41,7 +41,7 @@ BEGIN
@Plan, @Plan,
@PlanType, @PlanType,
@Seats, @Seats,
@MaxSubvaults, @MaxCollections,
@StripeCustomerId, @StripeCustomerId,
@StripeSubscriptionId, @StripeSubscriptionId,
@Enabled, @Enabled,

View File

@ -6,7 +6,7 @@
@Plan NVARCHAR(20), @Plan NVARCHAR(20),
@PlanType TINYINT, @PlanType TINYINT,
@Seats SMALLINT, @Seats SMALLINT,
@MaxSubvaults SMALLINT, @MaxCollections SMALLINT,
@StripeCustomerId VARCHAR(50), @StripeCustomerId VARCHAR(50),
@StripeSubscriptionId VARCHAR(50), @StripeSubscriptionId VARCHAR(50),
@Enabled BIT, @Enabled BIT,
@ -26,7 +26,7 @@ BEGIN
[Plan] = @Plan, [Plan] = @Plan,
[PlanType] = @PlanType, [PlanType] = @PlanType,
[Seats] = @Seats, [Seats] = @Seats,
[MaxSubvaults] = @MaxSubvaults, [MaxCollections] = @MaxCollections,
[StripeCustomerId] = @StripeCustomerId, [StripeCustomerId] = @StripeCustomerId,
[StripeSubscriptionId] = @StripeSubscriptionId, [StripeSubscriptionId] = @StripeSubscriptionId,
[Enabled] = @Enabled, [Enabled] = @Enabled,

View File

@ -1,18 +1,18 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_Create] CREATE PROCEDURE [dbo].[CollectionCipher_Create]
@SubvaultId UNIQUEIDENTIFIER, @CollectionId UNIQUEIDENTIFIER,
@CipherId UNIQUEIDENTIFIER @CipherId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
INSERT INTO [dbo].[SubvaultCipher] INSERT INTO [dbo].[CollectionCipher]
( (
[SubvaultId], [CollectionId],
[CipherId] [CipherId]
) )
VALUES VALUES
( (
@SubvaultId, @CollectionId,
@CipherId @CipherId
) )

View File

@ -1,5 +1,5 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_Delete] CREATE PROCEDURE [dbo].[CollectionCipher_Delete]
@SubvaultId UNIQUEIDENTIFIER, @CollectionId UNIQUEIDENTIFIER,
@CipherId UNIQUEIDENTIFIER @CipherId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,9 +7,9 @@ BEGIN
DELETE DELETE
FROM FROM
[dbo].[SubvaultCipher] [dbo].[CollectionCipher]
WHERE WHERE
[SubvaultId] = @SubvaultId [CollectionId] = @CollectionId
AND [CipherId] = @CipherId AND [CipherId] = @CipherId
DECLARE @OrganizationId UNIQUEIDENTIFIER = (SELECT TOP 1 [OrganizationId] FROM [dbo].[Cipher] WHERE [Id] = @CipherId) DECLARE @OrganizationId UNIQUEIDENTIFIER = (SELECT TOP 1 [OrganizationId] FROM [dbo].[Cipher] WHERE [Id] = @CipherId)

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_ReadByOrganizationId] CREATE PROCEDURE [dbo].[CollectionCipher_ReadByOrganizationId]
@OrganizationId UNIQUEIDENTIFIER @OrganizationId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,9 +7,9 @@ BEGIN
SELECT SELECT
SC.* SC.*
FROM FROM
[dbo].[SubvaultCipher] SC [dbo].[CollectionCipher] SC
INNER JOIN INNER JOIN
[dbo].[Subvault] S ON S.[Id] = SC.[SubvaultId] [dbo].[Collection] S ON S.[Id] = SC.[CollectionId]
WHERE WHERE
S.[OrganizationId] = @OrganizationId S.[OrganizationId] = @OrganizationId
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_ReadByUserId] CREATE PROCEDURE [dbo].[CollectionCipher_ReadByUserId]
@UserId UNIQUEIDENTIFIER @UserId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,14 +7,14 @@ BEGIN
SELECT SELECT
SC.* SC.*
FROM FROM
[dbo].[SubvaultCipher] SC [dbo].[CollectionCipher] SC
INNER JOIN INNER JOIN
[dbo].[Subvault] S ON S.[Id] = SC.[SubvaultId] [dbo].[Collection] S ON S.[Id] = SC.[CollectionId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = S.[OrganizationId] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = S.[OrganizationId] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON OU.[AccessAllCollections] = 0 AND SU.[CollectionId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[Status] = 2 -- Confirmed OU.[Status] = 2 -- Confirmed
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_ReadByUserIdCipherId] CREATE PROCEDURE [dbo].[CollectionCipher_ReadByUserIdCipherId]
@UserId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER,
@CipherId UNIQUEIDENTIFIER @CipherId UNIQUEIDENTIFIER
AS AS
@ -8,15 +8,15 @@ BEGIN
SELECT SELECT
SC.* SC.*
FROM FROM
[dbo].[SubvaultCipher] SC [dbo].[CollectionCipher] SC
INNER JOIN INNER JOIN
[dbo].[Subvault] S ON S.[Id] = SC.[SubvaultId] [dbo].[Collection] S ON S.[Id] = SC.[CollectionId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = S.[OrganizationId] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = S.[OrganizationId] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON OU.[AccessAllCollections] = 0 AND SU.[CollectionId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
SC.[CipherId] = @CipherId SC.[CipherId] = @CipherId
AND OU.[Status] = 2 -- Confirmed AND OU.[Status] = 2 -- Confirmed
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
END END

View File

@ -1,7 +1,7 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_UpdateSubvaults] CREATE PROCEDURE [dbo].[CollectionCipher_UpdateCollections]
@CipherId UNIQUEIDENTIFIER, @CipherId UNIQUEIDENTIFIER,
@UserId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER,
@SubvaultIds AS [dbo].[GuidIdArray] READONLY @CollectionIds AS [dbo].[GuidIdArray] READONLY
AS AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
@ -15,32 +15,32 @@ BEGIN
[Id] = @CipherId [Id] = @CipherId
) )
;WITH [AvailableSubvaultsCTE] AS( ;WITH [AvailableCollectionsCTE] AS(
SELECT SELECT
S.[Id] S.[Id]
FROM FROM
[dbo].[Subvault] S [dbo].[Collection] S
INNER JOIN INNER JOIN
[Organization] O ON O.[Id] = S.[OrganizationId] [Organization] O ON O.[Id] = S.[OrganizationId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON OU.[AccessAllCollections] = 0 AND SU.[CollectionId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
O.[Id] = @OrgId O.[Id] = @OrgId
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND OU.[Status] = 2 -- Confirmed AND OU.[Status] = 2 -- Confirmed
AND (OU.[AccessAllSubvaults] = 1 OR SU.[ReadOnly] = 0) AND (OU.[AccessAllCollections] = 1 OR SU.[ReadOnly] = 0)
) )
MERGE MERGE
[dbo].[SubvaultCipher] AS [Target] [dbo].[CollectionCipher] AS [Target]
USING USING
@SubvaultIds AS [Source] @CollectionIds AS [Source]
ON ON
[Target].[SubvaultId] = [Source].[Id] [Target].[CollectionId] = [Source].[Id]
AND [Target].[CipherId] = @CipherId AND [Target].[CipherId] = @CipherId
WHEN NOT MATCHED BY TARGET WHEN NOT MATCHED BY TARGET
AND [Source].[Id] IN (SELECT [Id] FROM [AvailableSubvaultsCTE]) THEN AND [Source].[Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) THEN
INSERT VALUES INSERT VALUES
( (
[Source].[Id], [Source].[Id],
@ -48,7 +48,7 @@ BEGIN
) )
WHEN NOT MATCHED BY SOURCE WHEN NOT MATCHED BY SOURCE
AND [Target].[CipherId] = @CipherId AND [Target].[CipherId] = @CipherId
AND [Target].[SubvaultId] IN (SELECT [Id] FROM [AvailableSubvaultsCTE]) THEN AND [Target].[CollectionId] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) THEN
DELETE DELETE
; ;

View File

@ -1,28 +1,28 @@
CREATE PROCEDURE [dbo].[SubvaultCipher_UpdateSubvaultsAdmin] CREATE PROCEDURE [dbo].[CollectionCipher_UpdateCollectionsAdmin]
@CipherId UNIQUEIDENTIFIER, @CipherId UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER,
@SubvaultIds AS [dbo].[GuidIdArray] READONLY @CollectionIds AS [dbo].[GuidIdArray] READONLY
AS AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
;WITH [AvailableSubvaultsCTE] AS( ;WITH [AvailableCollectionsCTE] AS(
SELECT SELECT
Id Id
FROM FROM
[dbo].[Subvault] [dbo].[Collection]
WHERE WHERE
OrganizationId = @OrganizationId OrganizationId = @OrganizationId
) )
MERGE MERGE
[dbo].[SubvaultCipher] AS [Target] [dbo].[CollectionCipher] AS [Target]
USING USING
@SubvaultIds AS [Source] @CollectionIds AS [Source]
ON ON
[Target].[SubvaultId] = [Source].[Id] [Target].[CollectionId] = [Source].[Id]
AND [Target].[CipherId] = @CipherId AND [Target].[CipherId] = @CipherId
WHEN NOT MATCHED BY TARGET WHEN NOT MATCHED BY TARGET
AND [Source].[Id] IN (SELECT [Id] FROM [AvailableSubvaultsCTE]) THEN AND [Source].[Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) THEN
INSERT VALUES INSERT VALUES
( (
[Source].[Id], [Source].[Id],

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultUserSubvaultDetails_ReadByUserId] CREATE PROCEDURE [dbo].[CollectionUserCollectionDetails_ReadByUserId]
@UserId UNIQUEIDENTIFIER @UserId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,7 +7,7 @@ BEGIN
SELECT SELECT
SU.* SU.*
FROM FROM
[dbo].[SubvaultUserSubvaultDetailsView] SU [dbo].[CollectionUserCollectionDetailsView] SU
INNER JOIN INNER JOIN
[OrganizationUser] OU ON SU.[OrganizationUserId] = OU.[Id] [OrganizationUser] OU ON SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE

View File

@ -1,5 +1,5 @@
CREATE PROCEDURE [dbo].[SubvaultUserUserDetails_ReadBySubvaultId] CREATE PROCEDURE [dbo].[CollectionUserUserDetails_ReadByCollectionId]
@SubvaultId UNIQUEIDENTIFIER @CollectionId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
@ -7,8 +7,8 @@ BEGIN
SELECT SELECT
* *
FROM FROM
[dbo].[SubvaultUserUserDetailsView] [dbo].[CollectionUserUserDetailsView]
WHERE WHERE
[AccessAllSubvaults] = 1 [AccessAllCollections] = 1
OR [SubvaultId] = @SubvaultId OR [CollectionId] = @CollectionId
END END

View File

@ -1,6 +1,6 @@
CREATE PROCEDURE [dbo].[SubvaultUser_Create] CREATE PROCEDURE [dbo].[CollectionUser_Create]
@Id UNIQUEIDENTIFIER, @Id UNIQUEIDENTIFIER,
@SubvaultId UNIQUEIDENTIFIER, @CollectionId UNIQUEIDENTIFIER,
@OrganizationUserId UNIQUEIDENTIFIER, @OrganizationUserId UNIQUEIDENTIFIER,
@ReadOnly BIT, @ReadOnly BIT,
@CreationDate DATETIME2(7), @CreationDate DATETIME2(7),
@ -9,10 +9,10 @@ AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
INSERT INTO [dbo].[SubvaultUser] INSERT INTO [dbo].[CollectionUser]
( (
[Id], [Id],
[SubvaultId], [CollectionId],
[OrganizationUserId], [OrganizationUserId],
[ReadOnly], [ReadOnly],
[CreationDate], [CreationDate],
@ -21,7 +21,7 @@ BEGIN
VALUES VALUES
( (
@Id, @Id,
@SubvaultId, @CollectionId,
@OrganizationUserId, @OrganizationUserId,
@ReadOnly, @ReadOnly,
@CreationDate, @CreationDate,

View File

@ -1,14 +1,14 @@
CREATE PROCEDURE [dbo].[SubvaultUser_DeleteById] CREATE PROCEDURE [dbo].[CollectionUser_DeleteById]
@Id UNIQUEIDENTIFIER @Id UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
DECLARE @OrganizationUserId UNIQUEIDENTIFIER = (SELECT TOP 1 [OrganizationUserId] FROM [dbo].[SubvaultUser] WHERE [Id] = @Id) DECLARE @OrganizationUserId UNIQUEIDENTIFIER = (SELECT TOP 1 [OrganizationUserId] FROM [dbo].[CollectionUser] WHERE [Id] = @Id)
DELETE DELETE
FROM FROM
[dbo].[SubvaultUser] [dbo].[CollectionUser]
WHERE WHERE
[Id] = @Id [Id] = @Id

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultUser_ReadById] CREATE PROCEDURE [dbo].[CollectionUser_ReadById]
@Id UNIQUEIDENTIFIER @Id UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,7 +7,7 @@ BEGIN
SELECT SELECT
* *
FROM FROM
[dbo].[SubvaultUserView] [dbo].[CollectionUserView]
WHERE WHERE
[Id] = @Id [Id] = @Id
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultUser_ReadByOrganizationUserId] CREATE PROCEDURE [dbo].[CollectionUser_ReadByOrganizationUserId]
@OrganizationUserId UNIQUEIDENTIFIER @OrganizationUserId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,7 +7,7 @@ BEGIN
SELECT SELECT
* *
FROM FROM
[dbo].[SubvaultUserView] [dbo].[CollectionUserView]
WHERE WHERE
[OrganizationUserId] = @OrganizationUserId [OrganizationUserId] = @OrganizationUserId
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[SubvaultUser_ReadCanEditByCipherIdUserId] CREATE PROCEDURE [dbo].[CollectionUser_ReadCanEditByCipherIdUserId]
@UserId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER,
@CipherId AS UNIQUEIDENTIFIER @CipherId AS UNIQUEIDENTIFIER
AS AS

View File

@ -1,6 +1,6 @@
CREATE PROCEDURE [dbo].[SubvaultUser_Update] CREATE PROCEDURE [dbo].[CollectionUser_Update]
@Id UNIQUEIDENTIFIER, @Id UNIQUEIDENTIFIER,
@SubvaultId UNIQUEIDENTIFIER, @CollectionId UNIQUEIDENTIFIER,
@OrganizationUserId UNIQUEIDENTIFIER, @OrganizationUserId UNIQUEIDENTIFIER,
@ReadOnly BIT, @ReadOnly BIT,
@CreationDate DATETIME2(7), @CreationDate DATETIME2(7),
@ -10,9 +10,9 @@ BEGIN
SET NOCOUNT ON SET NOCOUNT ON
UPDATE UPDATE
[dbo].[SubvaultUser] [dbo].[CollectionUser]
SET SET
[SubvaultId] = @SubvaultId, [CollectionId] = @CollectionId,
[OrganizationUserId] = @OrganizationUserId, [OrganizationUserId] = @OrganizationUserId,
[ReadOnly] = @ReadOnly, [ReadOnly] = @ReadOnly,
[CreationDate] = @CreationDate, [CreationDate] = @CreationDate,

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_Create] CREATE PROCEDURE [dbo].[Collection_Create]
@Id UNIQUEIDENTIFIER, @Id UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER,
@Name VARCHAR(MAX), @Name VARCHAR(MAX),
@ -8,7 +8,7 @@ AS
BEGIN BEGIN
SET NOCOUNT ON SET NOCOUNT ON
INSERT INTO [dbo].[Subvault] INSERT INTO [dbo].[Collection]
( (
[Id], [Id],
[OrganizationId], [OrganizationId],

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_DeleteById] CREATE PROCEDURE [dbo].[Collection_DeleteById]
@Id UNIQUEIDENTIFIER @Id UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -6,7 +6,7 @@ BEGIN
DELETE DELETE
FROM FROM
[dbo].[Subvault] [dbo].[Collection]
WHERE WHERE
[Id] = @Id [Id] = @Id
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_ReadById] CREATE PROCEDURE [dbo].[Collection_ReadById]
@Id UNIQUEIDENTIFIER @Id UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,7 +7,7 @@ BEGIN
SELECT SELECT
* *
FROM FROM
[dbo].[SubvaultView] [dbo].[CollectionView]
WHERE WHERE
[Id] = @Id [Id] = @Id
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_ReadByOrganizationId] CREATE PROCEDURE [dbo].[Collection_ReadByOrganizationId]
@OrganizationId UNIQUEIDENTIFIER @OrganizationId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,7 +7,7 @@ BEGIN
SELECT SELECT
S.* S.*
FROM FROM
[dbo].[SubvaultView] S [dbo].[CollectionView] S
WHERE WHERE
S.[OrganizationId] = @OrganizationId S.[OrganizationId] = @OrganizationId
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_ReadByUserId] CREATE PROCEDURE [dbo].[Collection_ReadByUserId]
@UserId UNIQUEIDENTIFIER @UserId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,15 +7,15 @@ BEGIN
SELECT SELECT
S.* S.*
FROM FROM
[dbo].[SubvaultView] S [dbo].[CollectionView] S
INNER JOIN INNER JOIN
[Organization] O ON O.[Id] = S.[OrganizationId] [Organization] O ON O.[Id] = S.[OrganizationId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON OU.[AccessAllCollections] = 0 AND SU.[CollectionId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[Status] = 2 -- Confirmed OU.[Status] = 2 -- Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL) AND (OU.[AccessAllCollections] = 1 OR SU.[CollectionId] IS NOT NULL)
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_ReadCountByOrganizationId] CREATE PROCEDURE [dbo].[Collection_ReadCountByOrganizationId]
@OrganizationId UNIQUEIDENTIFIER @OrganizationId UNIQUEIDENTIFIER
AS AS
BEGIN BEGIN
@ -7,7 +7,7 @@ BEGIN
SELECT SELECT
COUNT(1) COUNT(1)
FROM FROM
[dbo].[Subvault] [dbo].[Collection]
WHERE WHERE
[OrganizationId] = @OrganizationId [OrganizationId] = @OrganizationId
END END

View File

@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[Subvault_Update] CREATE PROCEDURE [dbo].[Collection_Update]
@Id UNIQUEIDENTIFIER, @Id UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER,
@Name VARCHAR(MAX), @Name VARCHAR(MAX),
@ -9,7 +9,7 @@ BEGIN
SET NOCOUNT ON SET NOCOUNT ON
UPDATE UPDATE
[dbo].[Subvault] [dbo].[Collection]
SET SET
[OrganizationId] = @OrganizationId, [OrganizationId] = @OrganizationId,
[Name] = @Name, [Name] = @Name,

View File

@ -6,7 +6,7 @@
[Plan] NVARCHAR (20) NOT NULL, [Plan] NVARCHAR (20) NOT NULL,
[PlanType] TINYINT NOT NULL, [PlanType] TINYINT NOT NULL,
[Seats] SMALLINT NULL, [Seats] SMALLINT NULL,
[MaxSubvaults] SMALLINT NULL, [MaxCollections] SMALLINT NULL,
[StripeCustomerId] VARCHAR (50) NULL, [StripeCustomerId] VARCHAR (50) NULL,
[StripeSubscriptionId] VARCHAR (50) NULL, [StripeSubscriptionId] VARCHAR (50) NULL,
[Enabled] BIT NOT NULL, [Enabled] BIT NOT NULL,

View File

@ -6,7 +6,7 @@
[Key] VARCHAR (MAX) NULL, [Key] VARCHAR (MAX) NULL,
[Status] TINYINT NOT NULL, [Status] TINYINT NOT NULL,
[Type] TINYINT NOT NULL, [Type] TINYINT NOT NULL,
[AccessAllSubvaults] BIT NOT NULL, [AccessAllCollections] BIT NOT NULL,
[CreationDate] DATETIME2 (7) NOT NULL, [CreationDate] DATETIME2 (7) NOT NULL,
[RevisionDate] DATETIME2 (7) NOT NULL, [RevisionDate] DATETIME2 (7) NOT NULL,
CONSTRAINT [PK_OrganizationUser] PRIMARY KEY CLUSTERED ([Id] ASC), CONSTRAINT [PK_OrganizationUser] PRIMARY KEY CLUSTERED ([Id] ASC),

View File

@ -1,10 +1,10 @@
CREATE TABLE [dbo].[Subvault] ( CREATE TABLE [dbo].[Collection] (
[Id] UNIQUEIDENTIFIER NOT NULL, [Id] UNIQUEIDENTIFIER NOT NULL,
[OrganizationId] UNIQUEIDENTIFIER NOT NULL, [OrganizationId] UNIQUEIDENTIFIER NOT NULL,
[Name] VARCHAR (MAX) NOT NULL, [Name] VARCHAR (MAX) NOT NULL,
[CreationDate] DATETIME2 (7) NOT NULL, [CreationDate] DATETIME2 (7) NOT NULL,
[RevisionDate] DATETIME2 (7) NOT NULL, [RevisionDate] DATETIME2 (7) NOT NULL,
CONSTRAINT [PK_Subvault] PRIMARY KEY CLUSTERED ([Id] ASC), CONSTRAINT [PK_Collection] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Subvault_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [dbo].[Organization] ([Id]) ON DELETE CASCADE CONSTRAINT [FK_Collection_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [dbo].[Organization] ([Id]) ON DELETE CASCADE
); );

View File

@ -1,13 +1,13 @@
CREATE TABLE [dbo].[SubvaultCipher] ( CREATE TABLE [dbo].[CollectionCipher] (
[SubvaultId] UNIQUEIDENTIFIER NOT NULL, [CollectionId] UNIQUEIDENTIFIER NOT NULL,
[CipherId] UNIQUEIDENTIFIER NOT NULL, [CipherId] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_SubvaultCipher] PRIMARY KEY CLUSTERED ([SubvaultId] ASC, [CipherId] ASC), CONSTRAINT [PK_CollectionCipher] PRIMARY KEY CLUSTERED ([CollectionId] ASC, [CipherId] ASC),
CONSTRAINT [FK_SubvaultCipher_Cipher] FOREIGN KEY ([CipherId]) REFERENCES [dbo].[Cipher] ([Id]) ON DELETE CASCADE, CONSTRAINT [FK_CollectionCipher_Cipher] FOREIGN KEY ([CipherId]) REFERENCES [dbo].[Cipher] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_SubvaultCipher_Subvault] FOREIGN KEY ([SubvaultId]) REFERENCES [dbo].[Subvault] ([Id]) ON DELETE CASCADE CONSTRAINT [FK_CollectionCipher_Collection] FOREIGN KEY ([CollectionId]) REFERENCES [dbo].[Collection] ([Id]) ON DELETE CASCADE
); );
GO GO
CREATE NONCLUSTERED INDEX [IX_SubvaultCipher_CipherId] CREATE NONCLUSTERED INDEX [IX_CollectionCipher_CipherId]
ON [dbo].[SubvaultCipher]([CipherId] ASC); ON [dbo].[CollectionCipher]([CipherId] ASC);

View File

@ -1,8 +1,8 @@
CREATE TABLE [dbo].[SubvaultGroup] ( CREATE TABLE [dbo].[CollectionGroup] (
[SubvaultId] UNIQUEIDENTIFIER NOT NULL, [CollectionId] UNIQUEIDENTIFIER NOT NULL,
[GroupId] UNIQUEIDENTIFIER NOT NULL, [GroupId] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_SubvaultGroup] PRIMARY KEY CLUSTERED ([SubvaultId] ASC, [GroupId] ASC), CONSTRAINT [PK_CollectionGroup] PRIMARY KEY CLUSTERED ([CollectionId] ASC, [GroupId] ASC),
CONSTRAINT [FK_SubvaultGroup_Group] FOREIGN KEY ([GroupId]) REFERENCES [dbo].[Group] ([Id]) ON DELETE CASCADE, CONSTRAINT [FK_CollectionGroup_Group] FOREIGN KEY ([GroupId]) REFERENCES [dbo].[Group] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_SubvaultGroup_Subvault] FOREIGN KEY ([SubvaultId]) REFERENCES [dbo].[Subvault] ([Id]) CONSTRAINT [FK_CollectionGroup_Collection] FOREIGN KEY ([CollectionId]) REFERENCES [dbo].[Collection] ([Id])
); );

View File

@ -1,17 +1,17 @@
CREATE TABLE [dbo].[SubvaultUser] ( CREATE TABLE [dbo].[CollectionUser] (
[Id] UNIQUEIDENTIFIER NOT NULL, [Id] UNIQUEIDENTIFIER NOT NULL,
[SubvaultId] UNIQUEIDENTIFIER NOT NULL, [CollectionId] UNIQUEIDENTIFIER NOT NULL,
[OrganizationUserId] UNIQUEIDENTIFIER NOT NULL, [OrganizationUserId] UNIQUEIDENTIFIER NOT NULL,
[ReadOnly] BIT NOT NULL, [ReadOnly] BIT NOT NULL,
[CreationDate] DATETIME2 (7) NOT NULL, [CreationDate] DATETIME2 (7) NOT NULL,
[RevisionDate] DATETIME2 (7) NOT NULL, [RevisionDate] DATETIME2 (7) NOT NULL,
CONSTRAINT [PK_SubvaultUser] PRIMARY KEY CLUSTERED ([Id] ASC), CONSTRAINT [PK_CollectionUser] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_SubvaultUser_OrganizationUser] FOREIGN KEY ([OrganizationUserId]) REFERENCES [dbo].[OrganizationUser] ([Id]), CONSTRAINT [FK_CollectionUser_OrganizationUser] FOREIGN KEY ([OrganizationUserId]) REFERENCES [dbo].[OrganizationUser] ([Id]),
CONSTRAINT [FK_SubvaultUser_Subvault] FOREIGN KEY ([SubvaultId]) REFERENCES [dbo].[Subvault] ([Id]) ON DELETE CASCADE CONSTRAINT [FK_CollectionUser_Collection] FOREIGN KEY ([CollectionId]) REFERENCES [dbo].[Collection] ([Id]) ON DELETE CASCADE
); );
GO GO
CREATE NONCLUSTERED INDEX [IX_SubvaultUser_SubvaultId] CREATE NONCLUSTERED INDEX [IX_CollectionUser_CollectionId]
ON [dbo].[SubvaultUser]([SubvaultId] ASC); ON [dbo].[CollectionUser]([CollectionId] ASC);

View File

@ -8,7 +8,7 @@ SELECT
ISNULL(U.[Email], OU.[Email]) Email, ISNULL(U.[Email], OU.[Email]) Email,
OU.[Status], OU.[Status],
OU.[Type], OU.[Type],
OU.[AccessAllSubvaults] OU.[AccessAllCollections]
FROM FROM
[dbo].[OrganizationUser] OU [dbo].[OrganizationUser] OU
LEFT JOIN LEFT JOIN

View File

@ -1,12 +1,12 @@
CREATE VIEW [dbo].[SubvaultUserSubvaultDetailsView] CREATE VIEW [dbo].[CollectionUserCollectionDetailsView]
AS AS
SELECT SELECT
SU.[Id], SU.[Id],
SU.[OrganizationUserId], SU.[OrganizationUserId],
S.[Name], S.[Name],
S.[Id] SubvaultId, S.[Id] CollectionId,
SU.[ReadOnly] SU.[ReadOnly]
FROM FROM
[dbo].[SubvaultUser] SU [dbo].[CollectionUser] SU
INNER JOIN INNER JOIN
[dbo].[Subvault] S ON S.[Id] = SU.[SubvaultId] [dbo].[Collection] S ON S.[Id] = SU.[CollectionId]

View File

@ -1,18 +1,18 @@
CREATE VIEW [dbo].[SubvaultUserUserDetailsView] CREATE VIEW [dbo].[CollectionUserUserDetailsView]
AS AS
SELECT SELECT
OU.[Id] AS [OrganizationUserId], OU.[Id] AS [OrganizationUserId],
OU.[AccessAllSubvaults], OU.[AccessAllCollections],
SU.[Id], SU.[Id],
SU.[SubvaultId], SU.[CollectionId],
U.[Name], U.[Name],
ISNULL(U.[Email], OU.[Email]) Email, ISNULL(U.[Email], OU.[Email]) Email,
OU.[Status], OU.[Status],
OU.[Type], OU.[Type],
CASE WHEN OU.[AccessAllSubvaults] = 0 AND SU.[ReadOnly] = 1 THEN 1 ELSE 0 END [ReadOnly] CASE WHEN OU.[AccessAllCollections] = 0 AND SU.[ReadOnly] = 1 THEN 1 ELSE 0 END [ReadOnly]
FROM FROM
[dbo].[OrganizationUser] OU [dbo].[OrganizationUser] OU
LEFT JOIN LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[OrganizationUserId] = OU.[Id] [dbo].[CollectionUser] SU ON OU.[AccessAllCollections] = 0 AND SU.[OrganizationUserId] = OU.[Id]
LEFT JOIN LEFT JOIN
[dbo].[User] U ON U.[Id] = OU.[UserId] [dbo].[User] U ON U.[Id] = OU.[UserId]

View File

@ -1,6 +1,6 @@
CREATE VIEW [dbo].[SubvaultUserView] CREATE VIEW [dbo].[CollectionUserView]
AS AS
SELECT SELECT
* *
FROM FROM
[dbo].[SubvaultUser] [dbo].[CollectionUser]

View File

@ -1,6 +1,6 @@
CREATE VIEW [dbo].[SubvaultView] CREATE VIEW [dbo].[CollectionView]
AS AS
SELECT SELECT
* *
FROM FROM
[dbo].[Subvault] [dbo].[Collection]