1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-16 01:51:21 +01:00

[Policy] Personal Ownership (#1013)

* Initial commit of disable personal vault policy

* Added new sproc // updated policy check (was missing conditionals)

* Updated DeMorgan's law logic
This commit is contained in:
Vincent Salucci 2020-12-11 10:45:26 -06:00 committed by GitHub
parent fee5c932db
commit 70f5fd5030
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 103 additions and 0 deletions

View File

@ -84,6 +84,7 @@ namespace Bit.Portal.Models
case PolicyType.SingleOrg:
case PolicyType.TwoFactorAuthentication:
case PolicyType.RequireSso:
case PolicyType.PersonalOwnership:
break;
default:
throw new ArgumentOutOfRangeException();

View File

@ -41,6 +41,11 @@ namespace Bit.Portal.Models
NameKey = "RequireSso";
DescriptionKey = "RequireSsoDescription";
break;
case PolicyType.PersonalOwnership:
NameKey = "PersonalOwnership";
DescriptionKey = "PersonalOwnershipDescription";
break;
default:
throw new ArgumentOutOfRangeException();

View File

@ -51,6 +51,17 @@
</div>
}
@if (Model.PolicyType == PolicyType.PersonalOwnership)
{
<div class="callout callout-warning" role="alert">
<h3 class="callout-heading">
<i class="fa fa-warning" *ngIf="icon" aria-hidden="true"></i>
@i18nService.T("Warning")
</h3>
@i18nService.T("PersonalOwnershipExemption")
</div>
}
<div asp-validation-summary="ModelOnly" class="alert alert-danger"></div>
<div class="form-group">

View File

@ -7,5 +7,6 @@
PasswordGenerator = 2,
SingleOrg = 3,
RequireSso = 4,
PersonalOwnership = 5,
}
}

View File

@ -23,6 +23,8 @@ namespace Bit.Core.Repositories
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId);
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
OrganizationUserStatusType? status = null);
Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId, Guid organizationId,
OrganizationUserStatusType? status = null);
Task UpdateGroupsAsync(Guid orgUserId, IEnumerable<Guid> groupIds);
Task CreateAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections);
Task ReplaceAsync(OrganizationUser obj, IEnumerable<SelectionReadOnly> collections);

View File

@ -184,6 +184,20 @@ namespace Bit.Core.Repositories.SqlServer
return results.ToList();
}
}
public async Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId,
Guid organizationId, OrganizationUserStatusType? status = null)
{
using (var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<OrganizationUserOrganizationDetails>(
"[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]",
new { UserId = userId, Status = status, OrganizationId = organizationId },
commandType: CommandType.StoredProcedure);
return results.SingleOrDefault();
}
}
public async Task UpdateGroupsAsync(Guid orgUserId, IEnumerable<Guid> groupIds)
{

View File

@ -566,4 +566,13 @@
<data name="RequireSsoExemption" xml:space="preserve">
<value>Organization Owners and Administrators are exempt from this policy's enforcement.</value>
</data>
<data name="PersonalOwnership" xml:space="preserve">
<value>Personal Ownership</value>
</data>
<data name="PersonalOwnershipDescription" xml:space="preserve">
<value>Require users to save vault items to an organization by removing the personal ownership option.</value>
</data>
<data name="PersonalOwnershipExemption" xml:space="preserve">
<value>Organization Owners and Administrators are exempt from this policy's enforcement.</value>
</data>
</root>

View File

@ -27,6 +27,7 @@ namespace Bit.Core.Services
private readonly IAttachmentStorageService _attachmentStorageService;
private readonly IEventService _eventService;
private readonly IUserService _userService;
private readonly IPolicyRepository _policyRepository;
private readonly GlobalSettings _globalSettings;
public CipherService(
@ -41,6 +42,7 @@ namespace Bit.Core.Services
IAttachmentStorageService attachmentStorageService,
IEventService eventService,
IUserService userService,
IPolicyRepository policyRepository,
GlobalSettings globalSettings)
{
_cipherRepository = cipherRepository;
@ -54,6 +56,7 @@ namespace Bit.Core.Services
_attachmentStorageService = attachmentStorageService;
_eventService = eventService;
_userService = userService;
_policyRepository = policyRepository;
_globalSettings = globalSettings;
}
@ -118,6 +121,21 @@ namespace Bit.Core.Services
}
else
{
// Make sure the user can save new ciphers to their personal vault
var userPolicies = await _policyRepository.GetManyByUserIdAsync(savingUserId);
if (userPolicies != null)
{
foreach (var policy in userPolicies.Where(p => p.Enabled && p.Type == PolicyType.PersonalOwnership))
{
var org = await _organizationUserRepository.GetDetailsByUserAsync(savingUserId, policy.OrganizationId,
OrganizationUserStatusType.Confirmed);
if(org != null && org.Enabled && org.UsePolicies
&& org.Type != OrganizationUserType.Admin && org.Type != OrganizationUserType.Owner)
{
throw new BadRequestException("Due to an Enterprise Policy, you are restricted from saving items to your personal vault.");
}
}
}
await _cipherRepository.CreateAsync(cipher);
}
await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_Created);

View File

@ -295,6 +295,7 @@
<Build Include="dbo\Stored Procedures\TaxRate_Create.sql" />
<Build Include="dbo\Stored Procedures\TaxRate_Archive.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdEmail.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId.sql" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
CREATE PROCEDURE [dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]
@UserId UNIQUEIDENTIFIER,
@Status TINYINT,
@OrganizationId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
*
FROM
[dbo].[OrganizationUserOrganizationDetailsView]
WHERE
[UserId] = @UserId
AND [OrganizationId] = @OrganizationId
AND (@Status IS NULL OR [Status] = @Status)
END

View File

@ -0,0 +1,24 @@
IF OBJECT_ID('[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]
END
GO
CREATE PROCEDURE [dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]
@UserId UNIQUEIDENTIFIER,
@Status TINYINT,
@OrganizationId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
*
FROM
[dbo].[OrganizationUserOrganizationDetailsView]
WHERE
[UserId] = @UserId
AND [OrganizationId] = @OrganizationId
AND (@Status IS NULL OR [Status] = @Status)
END
GO