mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 06:13:38 +00:00
remove single org exemption for admins/owners when auto confirm is enabled (#17050)
This commit is contained in:
@@ -554,6 +554,77 @@ describe("PolicyService", () => {
|
|||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("SingleOrg policy exemptions", () => {
|
||||||
|
it("returns true for SingleOrg policy when AutoConfirm is enabled, even for users who can manage policies", async () => {
|
||||||
|
singleUserState.nextState(
|
||||||
|
arrayToRecord([
|
||||||
|
policyData("policy1", "org6", PolicyType.SingleOrg, true),
|
||||||
|
policyData("policy2", "org6", PolicyType.AutoConfirm, true),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await firstValueFrom(
|
||||||
|
policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns false for SingleOrg policy when user can manage policies and AutoConfirm is not enabled", async () => {
|
||||||
|
singleUserState.nextState(
|
||||||
|
arrayToRecord([policyData("policy1", "org6", PolicyType.SingleOrg, true)]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await firstValueFrom(
|
||||||
|
policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns false for SingleOrg policy when user can manage policies and AutoConfirm is disabled", async () => {
|
||||||
|
singleUserState.nextState(
|
||||||
|
arrayToRecord([
|
||||||
|
policyData("policy1", "org6", PolicyType.SingleOrg, true),
|
||||||
|
policyData("policy2", "org6", PolicyType.AutoConfirm, false),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await firstValueFrom(
|
||||||
|
policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns true for SingleOrg policy for regular users when AutoConfirm is not enabled", async () => {
|
||||||
|
singleUserState.nextState(
|
||||||
|
arrayToRecord([policyData("policy1", "org1", PolicyType.SingleOrg, true)]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await firstValueFrom(
|
||||||
|
policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns true for SingleOrg policy when AutoConfirm is enabled in a different organization", async () => {
|
||||||
|
singleUserState.nextState(
|
||||||
|
arrayToRecord([
|
||||||
|
policyData("policy1", "org6", PolicyType.SingleOrg, true),
|
||||||
|
policyData("policy2", "org1", PolicyType.AutoConfirm, true),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await firstValueFrom(
|
||||||
|
policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("combinePoliciesIntoMasterPasswordPolicyOptions", () => {
|
describe("combinePoliciesIntoMasterPasswordPolicyOptions", () => {
|
||||||
|
|||||||
@@ -40,18 +40,16 @@ export class DefaultPolicyService implements PolicyService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
policiesByType$(policyType: PolicyType, userId: UserId) {
|
policiesByType$(policyType: PolicyType, userId: UserId) {
|
||||||
const filteredPolicies$ = this.policies$(userId).pipe(
|
|
||||||
map((policies) => policies.filter((p) => p.type === policyType)),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
throw new Error("No userId provided");
|
throw new Error("No userId provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allPolicies$ = this.policies$(userId);
|
||||||
const organizations$ = this.organizationService.organizations$(userId);
|
const organizations$ = this.organizationService.organizations$(userId);
|
||||||
|
|
||||||
return combineLatest([filteredPolicies$, organizations$]).pipe(
|
return combineLatest([allPolicies$, organizations$]).pipe(
|
||||||
map(([policies, organizations]) => this.enforcedPolicyFilter(policies, organizations)),
|
map(([policies, organizations]) => this.enforcedPolicyFilter(policies, organizations)),
|
||||||
|
map((policies) => policies.filter((p) => p.type === policyType)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ export class DefaultPolicyService implements PolicyService {
|
|||||||
policy.enabled &&
|
policy.enabled &&
|
||||||
organization.status >= OrganizationUserStatusType.Accepted &&
|
organization.status >= OrganizationUserStatusType.Accepted &&
|
||||||
organization.usePolicies &&
|
organization.usePolicies &&
|
||||||
!this.isExemptFromPolicy(policy.type, organization)
|
!this.isExemptFromPolicy(policy.type, organization, policies)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -265,7 +263,11 @@ export class DefaultPolicyService implements PolicyService {
|
|||||||
* Determines whether an orgUser is exempt from a specific policy because of their role
|
* Determines whether an orgUser is exempt from a specific policy because of their role
|
||||||
* Generally orgUsers who can manage policies are exempt from them, but some policies are stricter
|
* Generally orgUsers who can manage policies are exempt from them, but some policies are stricter
|
||||||
*/
|
*/
|
||||||
private isExemptFromPolicy(policyType: PolicyType, organization: Organization) {
|
private isExemptFromPolicy(
|
||||||
|
policyType: PolicyType,
|
||||||
|
organization: Organization,
|
||||||
|
allPolicies: Policy[],
|
||||||
|
) {
|
||||||
switch (policyType) {
|
switch (policyType) {
|
||||||
case PolicyType.MaximumVaultTimeout:
|
case PolicyType.MaximumVaultTimeout:
|
||||||
// Max Vault Timeout applies to everyone except owners
|
// Max Vault Timeout applies to everyone except owners
|
||||||
@@ -286,6 +288,14 @@ export class DefaultPolicyService implements PolicyService {
|
|||||||
case PolicyType.OrganizationDataOwnership:
|
case PolicyType.OrganizationDataOwnership:
|
||||||
// organization data ownership policy applies to everyone except admins and owners
|
// organization data ownership policy applies to everyone except admins and owners
|
||||||
return organization.isAdmin;
|
return organization.isAdmin;
|
||||||
|
case PolicyType.SingleOrg:
|
||||||
|
// Check if AutoConfirm policy is enabled for this organization
|
||||||
|
return allPolicies.find(
|
||||||
|
(p) =>
|
||||||
|
p.organizationId === organization.id && p.type === PolicyType.AutoConfirm && p.enabled,
|
||||||
|
)
|
||||||
|
? false
|
||||||
|
: organization.canManagePolicies;
|
||||||
default:
|
default:
|
||||||
return organization.canManagePolicies;
|
return organization.canManagePolicies;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user