1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-01 23:31:41 +01:00

Exempt owners and admins from single org and 2FA policy (#1171)

* Fix single org policy when creating organization

Exclude owners and admins from policy when creating new org

* Fix single org and 2FA policy on accepting invite

Exclude owners and admins from policies

* Remove looped async calls

* Fix code style and formatting
This commit is contained in:
Thomas Rittson 2021-03-03 08:15:42 +10:00 committed by GitHub
parent c2d34d7271
commit a18e1b7dca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 30 deletions

View File

@ -163,7 +163,16 @@ namespace Bit.Api.Controllers
}
var policies = await _policyRepository.GetManyByUserIdAsync(user.Id);
if (policies.Any(policy => policy.Enabled && policy.Type == PolicyType.SingleOrg))
var orgUsers = await _organizationUserRepository.GetManyByUserAsync(user.Id);
var orgsWithSingleOrgPolicy = policies.Where(p => p.Enabled && p.Type == PolicyType.SingleOrg)
.Select(p => p.OrganizationId);
var blockedBySingleOrgPolicy = orgUsers.Any(ou => ou.Type != OrganizationUserType.Owner &&
ou.Type != OrganizationUserType.Admin &&
ou.Status != OrganizationUserStatusType.Invited &&
orgsWithSingleOrgPolicy.Contains(ou.OrganizationId));
if (blockedBySingleOrgPolicy)
{
throw new Exception("You may not create an organization. You belong to an organization " +
"which has a policy that prohibits you from being a member of any other organization.");

View File

@ -1155,39 +1155,49 @@ namespace Bit.Core.Services
}
}
ICollection<Policy> orgPolicies = null;
ICollection<Policy> userPolicies = null;
async Task<bool> hasPolicyAsync(PolicyType policyType, bool useUserPolicies = false)
bool notExempt(OrganizationUser organizationUser)
{
var policies = useUserPolicies ?
userPolicies = userPolicies ?? await _policyRepository.GetManyByUserIdAsync(user.Id) :
orgPolicies = orgPolicies ?? await _policyRepository.GetManyByOrganizationIdAsync(orgUser.OrganizationId);
return policies.Any(p => p.Type == policyType && p.Enabled);
return organizationUser.Type != OrganizationUserType.Owner &&
organizationUser.Type != OrganizationUserType.Admin;
}
var userOrgs = await _organizationUserRepository.GetManyByUserAsync(user.Id);
if (userOrgs.Any(ou => ou.OrganizationId != orgUser.OrganizationId && ou.Status != OrganizationUserStatusType.Invited))
{
if (await hasPolicyAsync(PolicyType.SingleOrg))
var allOrgUsers = await _organizationUserRepository.GetManyByUserAsync(user.Id);
// Enforce Single Organization Policy of organization user is trying to join
var thisSingleOrgPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(orgUser.OrganizationId, PolicyType.SingleOrg);
if (thisSingleOrgPolicy != null &&
thisSingleOrgPolicy.Enabled &&
notExempt(orgUser) &&
allOrgUsers.Any(ou => ou.OrganizationId != orgUser.OrganizationId))
{
throw new BadRequestException("You may not join this organization until you leave or remove " +
"all other organizations.");
}
if (await hasPolicyAsync(PolicyType.SingleOrg, true))
// Enforce Single Organization Policy of other organizations user is a member of
var policies = await _policyRepository.GetManyByUserIdAsync(user.Id);
var orgsWithSingleOrgPolicy = policies.Where(p => p.Enabled && p.Type == PolicyType.SingleOrg)
.Select(p => p.OrganizationId);
var blockedBySingleOrgPolicy = allOrgUsers.Any(ou => notExempt(ou) &&
ou.Status != OrganizationUserStatusType.Invited &&
orgsWithSingleOrgPolicy.Contains(ou.OrganizationId));
if (blockedBySingleOrgPolicy)
{
throw new BadRequestException("You cannot join this organization because you are a member of " +
"an organization which forbids it");
}
}
if (!await userService.TwoFactorIsEnabledAsync(user))
{
if (await hasPolicyAsync(PolicyType.TwoFactorAuthentication))
var twoFactorPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(orgUser.OrganizationId, PolicyType.TwoFactorAuthentication);
if (!await userService.TwoFactorIsEnabledAsync(user) &&
twoFactorPolicy != null &&
twoFactorPolicy.Enabled &&
notExempt(orgUser))
{
throw new BadRequestException("You cannot join this organization until you enable " +
"two-step login on your user account.");
}
}
orgUser.Status = OrganizationUserStatusType.Accepted;
orgUser.UserId = user.Id;