1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-04 14:13:28 +01:00

Flag for org users to access all subvaults

This commit is contained in:
Kyle Spearrin 2017-04-20 23:50:12 -04:00
parent aa5b79df2b
commit b0b6cac97b
26 changed files with 139 additions and 106 deletions

View File

@ -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.Subvaults?.Select(s => s.ToSubvaultUser())); model.AccessAllSubvaults, model.Subvaults?.Select(s => s.ToSubvaultUser()));
} }
[HttpPut("{id}/reinvite")] [HttpPut("{id}/reinvite")]

View File

@ -12,6 +12,7 @@ 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 IEnumerable<OrganizationUserSubvaultRequestModel> Subvaults { get; set; } public IEnumerable<OrganizationUserSubvaultRequestModel> Subvaults { get; set; }
} }
@ -31,11 +32,13 @@ 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 IEnumerable<OrganizationUserSubvaultRequestModel> Subvaults { get; set; } public IEnumerable<OrganizationUserSubvaultRequestModel> Subvaults { get; set; }
public OrganizationUser ToOrganizationUser(OrganizationUser existingUser) public OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
{ {
existingUser.Type = Type.Value; existingUser.Type = Type.Value;
existingUser.AccessAllSubvaults = AccessAllSubvaults;
return existingUser; return existingUser;
} }
} }

View File

@ -22,6 +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;
} }
public string Id { get; set; } public string Id { get; set; }
@ -30,6 +31,7 @@ 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 class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel public class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel

View File

@ -15,9 +15,10 @@ namespace Bit.Core.Models.Api
throw new ArgumentNullException(nameof(subvaultUser)); throw new ArgumentNullException(nameof(subvaultUser));
} }
Id = subvaultUser.Id.ToString(); Id = subvaultUser.Id?.ToString();
OrganizationUserId = subvaultUser.OrganizationUserId.ToString(); OrganizationUserId = subvaultUser.OrganizationUserId.ToString();
SubvaultId = subvaultUser.SubvaultId.ToString(); SubvaultId = subvaultUser.SubvaultId?.ToString();
AccessAllSubvaults = subvaultUser.AccessAllSubvaults;
Name = subvaultUser.Name; Name = subvaultUser.Name;
Email = subvaultUser.Email; Email = subvaultUser.Email;
Type = subvaultUser.Type; Type = subvaultUser.Type;
@ -28,6 +29,7 @@ namespace Bit.Core.Models.Api
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 SubvaultId { get; set; }
public bool AccessAllSubvaults { 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,5 +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; }
} }
} }

View File

@ -4,9 +4,10 @@ namespace Bit.Core.Models.Data
{ {
public class SubvaultUserUserDetails public class SubvaultUserUserDetails
{ {
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? SubvaultId { get; set; }
public bool AccessAllSubvaults { 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,6 +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 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

@ -19,7 +19,7 @@ namespace Bit.Core.Services
Task DeleteAsync(Organization organization); Task DeleteAsync(Organization organization);
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, IEnumerable<SubvaultUser> subvaults); Enums.OrganizationUserType type, bool accessAllSubvaults, IEnumerable<SubvaultUser> subvaults);
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);

View File

@ -475,7 +475,7 @@ namespace Bit.Core.Services
$"{plan.MaxAdditionalSeats.GetValueOrDefault(0)} additional users."); $"{plan.MaxAdditionalSeats.GetValueOrDefault(0)} additional users.");
} }
if(plan.Type == Enums.PlanType.Free) if(plan.Type == PlanType.Free)
{ {
var ownerExistingOrgCount = var ownerExistingOrgCount =
await _organizationUserRepository.GetCountByFreeOrganizationAdminUserAsync(signup.Owner.Id); await _organizationUserRepository.GetCountByFreeOrganizationAdminUserAsync(signup.Owner.Id);
@ -555,6 +555,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,
CreationDate = DateTime.UtcNow, CreationDate = DateTime.UtcNow,
RevisionDate = DateTime.UtcNow RevisionDate = DateTime.UtcNow
}; };
@ -631,7 +632,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, IEnumerable<SubvaultUser> subvaults) OrganizationUserType type, bool accessAllSubvaults, IEnumerable<SubvaultUser> subvaults)
{ {
var organization = await _organizationRepository.GetByIdAsync(organizationId); var organization = await _organizationRepository.GetByIdAsync(organizationId);
if(organization == null) if(organization == null)
@ -664,12 +665,16 @@ namespace Bit.Core.Services
Key = null, Key = null,
Type = type, Type = type,
Status = OrganizationUserStatusType.Invited, Status = OrganizationUserStatusType.Invited,
AccessAllSubvaults = accessAllSubvaults,
CreationDate = DateTime.UtcNow, CreationDate = DateTime.UtcNow,
RevisionDate = DateTime.UtcNow RevisionDate = DateTime.UtcNow
}; };
await _organizationUserRepository.CreateAsync(orgUser); await _organizationUserRepository.CreateAsync(orgUser);
await SaveUserSubvaultsAsync(orgUser, subvaults, true); if(!orgUser.AccessAllSubvaults && subvaults.Any())
{
await SaveUserSubvaultsAsync(orgUser, subvaults, true);
}
await SendInviteAsync(orgUser); await SendInviteAsync(orgUser);
return orgUser; return orgUser;
@ -786,6 +791,12 @@ namespace Bit.Core.Services
} }
await _organizationUserRepository.ReplaceAsync(user); await _organizationUserRepository.ReplaceAsync(user);
if(user.AccessAllSubvaults)
{
// We don't need any subvaults if we're flagged to have all access.
subvaults = new List<SubvaultUser>();
}
await SaveUserSubvaultsAsync(user, subvaults, false); await SaveUserSubvaultsAsync(user, subvaults, false);
} }

View File

@ -5,22 +5,22 @@ BEGIN
;WITH [CTE] AS( ;WITH [CTE] AS(
SELECT SELECT
CASE WHEN SU.[ReadOnly] = 0 THEN 1 ELSE 0 END [CanEdit] CASE WHEN OU.[AccessAllSubvaults] = 1 OR SU.[ReadOnly] = 0 THEN 1 ELSE 0 END [CanEdit]
FROM FROM
[dbo].[SubvaultUser] SU [dbo].[Cipher] C
INNER JOIN INNER JOIN
[dbo].[SubvaultCipher] SC ON SC.SubvaultId = SU.SubvaultId [dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId]
INNER JOIN INNER JOIN
[dbo].[Cipher] C ON SC.[CipherId] = C.[Id] [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
INNER JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.Id = SU.OrganizationUserId AND OU.OrganizationId = C.OrganizationId [dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id]
INNER JOIN LEFT JOIN
[dbo].[Organization] O ON O.Id = C.OrganizationId [dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.[Id] = @CipherId C.[Id] = @CipherId
AND OU.[UserId] = @UserId
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)
) )
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

@ -9,23 +9,23 @@ BEGIN
C.* C.*
FROM FROM
[dbo].[CipherDetails](@UserId) C [dbo].[CipherDetails](@UserId) C
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId]
LEFT JOIN LEFT JOIN
[dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId] [dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.Id = @Id C.Id = @Id
AND ( AND (
C.[UserId] = @UserId C.[UserId] = @UserId
OR ( OR (
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[UserId] = @UserId
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)
) )
) )
END END

View File

@ -9,23 +9,23 @@ BEGIN
C.* C.*
FROM FROM
[dbo].[CipherDetails](@UserId) C [dbo].[CipherDetails](@UserId) C
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId]
LEFT JOIN LEFT JOIN
[dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId] [dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.[Type] = @Type C.[Type] = @Type
AND ( AND (
C.[UserId] = @UserId C.[UserId] = @UserId
OR ( OR (
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[UserId] = @UserId
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)
) )
) )
END END

View File

@ -8,20 +8,20 @@ BEGIN
C.* C.*
FROM FROM
[dbo].[CipherDetails](@UserId) C [dbo].[CipherDetails](@UserId) C
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId]
LEFT JOIN LEFT JOIN
[dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId] [dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] 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.[UserId] = @UserId
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)
) )
END END

View File

@ -8,16 +8,16 @@ BEGIN
C.* C.*
FROM FROM
[dbo].[CipherDetails](@UserId) C [dbo].[CipherDetails](@UserId) C
INNER JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND SC.[CipherId] = C.[Id]
INNER JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId]
INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId]
INNER JOIN INNER JOIN
[dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId] [dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId]
INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[UserId] = @UserId 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)
END END

View File

@ -13,23 +13,23 @@ BEGIN
END [Edit] END [Edit]
FROM FROM
[dbo].[CipherDetails](@UserId) C [dbo].[CipherDetails](@UserId) C
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId]
LEFT JOIN LEFT JOIN
[dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId] [dbo].[Organization] O ON C.[UserId] IS NULL AND O.[Id] = C.[OrganizationId]
LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultCipher] SC ON C.[UserId] IS NULL AND OU.[AccessAllSubvaults] = 0 AND SC.[CipherId] = C.[Id]
LEFT JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
C.Id = @Id C.Id = @Id
AND ( AND (
C.[UserId] = @UserId C.[UserId] = @UserId
OR ( OR (
C.[UserId] IS NULL C.[UserId] IS NULL
AND OU.[UserId] = @UserId
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)
) )
) )
END END

View File

@ -24,21 +24,21 @@ BEGIN
WHERE WHERE
[Id] = @Id [Id] = @Id
;WITH [AvailableSubvaultsCTE] AS( ;WITH [AvailableSubvaultsCTE] AS(
SELECT SELECT
SU.SubvaultId S.[Id]
FROM FROM
[dbo].[SubvaultUser] SU [dbo].[Subvault] S
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId] [Organization] O ON O.[Id] = S.[OrganizationId]
INNER JOIN INNER JOIN
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId] [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[UserId] = @UserId OU.[Status] = 2 -- Confirmed
AND SU.[ReadOnly] = 0
AND OU.[Status] = 2 -- Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[ReadOnly] = 0)
) )
INSERT INTO [dbo].[SubvaultCipher] INSERT INTO [dbo].[SubvaultCipher]
( (
@ -46,10 +46,10 @@ BEGIN
[CipherId] [CipherId]
) )
SELECT SELECT
Id, [Id],
@Id @Id
FROM FROM
@SubvaultIds @SubvaultIds
WHERE WHERE
Id IN (SELECT SubvaultId FROM [AvailableSubvaultsCTE]) [Id] IN (SELECT [Id] FROM [AvailableSubvaultsCTE])
END END

View File

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

View File

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

View File

@ -9,10 +9,12 @@ BEGIN
FROM FROM
[dbo].[SubvaultCipher] SC [dbo].[SubvaultCipher] SC
INNER JOIN INNER JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] [dbo].[Subvault] S ON S.[Id] = SC.[SubvaultId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId] [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = S.[OrganizationId] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[UserId] = @UserId OU.[Status] = 2 -- Confirmed
AND OU.[Status] = 2 -- Confirmed AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL)
END END

View File

@ -10,11 +10,13 @@ BEGIN
FROM FROM
[dbo].[SubvaultCipher] SC [dbo].[SubvaultCipher] SC
INNER JOIN INNER JOIN
[dbo].[SubvaultUser] SU ON SU.[SubvaultId] = SC.[SubvaultId] [dbo].[Subvault] S ON S.[Id] = SC.[SubvaultId]
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId] [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = S.[OrganizationId] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
SC.[CipherId] = @CipherId SC.[CipherId] = @CipherId
AND OU.[UserId] = @UserId
AND OU.[Status] = 2 -- Confirmed AND OU.[Status] = 2 -- Confirmed
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL)
END END

View File

@ -8,18 +8,19 @@ BEGIN
;WITH [AvailableSubvaultsCTE] AS( ;WITH [AvailableSubvaultsCTE] AS(
SELECT SELECT
SU.SubvaultId S.[Id]
FROM FROM
[dbo].[SubvaultUser] SU [dbo].[Subvault] S
INNER JOIN INNER JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId] [Organization] O ON O.[Id] = S.[OrganizationId]
INNER JOIN INNER JOIN
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId] [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
LEFT JOIN
[dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[UserId] = @UserId OU.[Status] = 2 -- Confirmed
AND SU.[ReadOnly] = 0
AND OU.[Status] = 2 -- Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[ReadOnly] = 0)
) )
MERGE MERGE
[dbo].[SubvaultCipher] AS [Target] [dbo].[SubvaultCipher] AS [Target]
@ -29,7 +30,7 @@ BEGIN
[Target].[SubvaultId] = [Source].[Id] [Target].[SubvaultId] = [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 [SubvaultId] FROM [AvailableSubvaultsCTE]) THEN AND [Source].[Id] IN (SELECT [Id] FROM [AvailableSubvaultsCTE]) THEN
INSERT VALUES INSERT VALUES
( (
[Source].[Id], [Source].[Id],
@ -37,7 +38,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 [SubvaultId] FROM [AvailableSubvaultsCTE]) THEN AND [Target].[SubvaultId] IN (SELECT [Id] FROM [AvailableSubvaultsCTE]) THEN
DELETE DELETE
; ;
END END

View File

@ -5,11 +5,10 @@ BEGIN
SET NOCOUNT ON SET NOCOUNT ON
SELECT SELECT
SU.* *
FROM FROM
[dbo].[SubvaultUserUserDetailsView] SU [dbo].[SubvaultUserUserDetailsView]
INNER JOIN
[OrganizationUser] OU ON SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
SU.[SubvaultId] = @SubvaultId [AccessAllSubvaults] = 1
OR [SubvaultId] = @SubvaultId
END END

View File

@ -9,13 +9,13 @@ BEGIN
FROM FROM
[dbo].[SubvaultView] S [dbo].[SubvaultView] S
INNER JOIN INNER JOIN
[SubvaultUser] SU ON SU.[SubvaultId] = S.[Id] [Organization] O ON O.[Id] = S.[OrganizationId]
INNER JOIN INNER JOIN
[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId] [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId
INNER JOIN LEFT JOIN
[Organization] O ON O.[Id] = OU.[OrganizationId] [dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 0 AND SU.[SubvaultId] = S.[Id] AND SU.[OrganizationUserId] = OU.[Id]
WHERE WHERE
OU.[UserId] = @UserId OU.[Status] = 2 -- Confirmed
AND OU.[Status] = 2 -- Confirmed
AND O.[Enabled] = 1 AND O.[Enabled] = 1
AND (OU.[AccessAllSubvaults] = 1 OR SU.[SubvaultId] IS NOT NULL)
END END

View File

@ -1,13 +1,14 @@
CREATE TABLE [dbo].[OrganizationUser] ( CREATE TABLE [dbo].[OrganizationUser] (
[Id] UNIQUEIDENTIFIER NOT NULL, [Id] UNIQUEIDENTIFIER NOT NULL,
[OrganizationId] UNIQUEIDENTIFIER NOT NULL, [OrganizationId] UNIQUEIDENTIFIER NOT NULL,
[UserId] UNIQUEIDENTIFIER NULL, [UserId] UNIQUEIDENTIFIER NULL,
[Email] NVARCHAR (50) NULL, [Email] NVARCHAR (50) NULL,
[Key] VARCHAR (MAX) NULL, [Key] VARCHAR (MAX) NULL,
[Status] TINYINT NOT NULL, [Status] TINYINT NOT NULL,
[Type] TINYINT NOT NULL, [Type] TINYINT NOT NULL,
[CreationDate] DATETIME2 (7) NOT NULL, [AccessAllSubvaults] BIT NOT NULL,
[RevisionDate] DATETIME2 (7) NOT NULL, [CreationDate] 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),
CONSTRAINT [FK_OrganizationUser_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [dbo].[Organization] ([Id]) ON DELETE CASCADE, CONSTRAINT [FK_OrganizationUser_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [dbo].[Organization] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_OrganizationUser_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) CONSTRAINT [FK_OrganizationUser_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id])

View File

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

View File

@ -1,17 +1,18 @@
CREATE VIEW [dbo].[SubvaultUserUserDetailsView] CREATE VIEW [dbo].[SubvaultUserUserDetailsView]
AS AS
SELECT SELECT
OU.[Id] AS [OrganizationUserId],
OU.[AccessAllSubvaults],
SU.[Id], SU.[Id],
SU.[OrganizationUserId],
SU.[SubvaultId], SU.[SubvaultId],
U.[Name], U.[Name],
ISNULL(U.[Email], OU.[Email]) Email, ISNULL(U.[Email], OU.[Email]) Email,
OU.[Status], OU.[Status],
OU.[Type], OU.[Type],
SU.[ReadOnly] CASE WHEN OU.[AccessAllSubvaults] = 0 AND SU.[ReadOnly] = 1 THEN 1 ELSE 0 END [ReadOnly]
FROM FROM
[dbo].[SubvaultUser] SU [dbo].[OrganizationUser] OU
INNER JOIN LEFT JOIN
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId] [dbo].[SubvaultUser] SU ON OU.[AccessAllSubvaults] = 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]