-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathSendControlsSyncPolicyEvent.cs
More file actions
118 lines (106 loc) · 5.33 KB
/
Copy pathSendControlsSyncPolicyEvent.cs
File metadata and controls
118 lines (106 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Models;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyUpdateEvents.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Repositories;
using Bit.Core.Tools.Services;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyEventHandlers;
/// <summary>
/// When the pm-31885-send-controls flag is active, syncs changes to the SendControls policy
/// back into the legacy DisableSend and SendOptions policy rows, enabling safe rollback.
/// </summary>
public class SendControlsSyncPolicyEvent(
IPolicyRepository policyRepository,
TimeProvider timeProvider,
ISendRepository sendRepository) : IOnPolicyPostUpdateEvent, IPolicyValidationEvent
{
public PolicyType Type => PolicyType.SendControls;
public async Task ExecutePostUpsertSideEffectAsync(
SavePolicyModel policyRequest,
Policy postUpsertedPolicyState,
Policy? previousPolicyState)
{
var sendControlsPolicyData =
postUpsertedPolicyState.GetDataModel<SendControlsPolicyData>();
await UpsertLegacyPolicyAsync<SendControlsPolicyData>(
postUpsertedPolicyState.OrganizationId,
PolicyType.DisableSend,
enabled: postUpsertedPolicyState.Enabled && sendControlsPolicyData.DisableSend,
policyData: null);
var sendOptionsData = new SendOptionsPolicyData { DisableHideEmail = sendControlsPolicyData.DisableHideEmail };
await UpsertLegacyPolicyAsync(
postUpsertedPolicyState.OrganizationId,
PolicyType.SendOptions,
enabled: postUpsertedPolicyState.Enabled && sendControlsPolicyData.DisableHideEmail,
policyData: sendOptionsData);
await UpdateSendsByPolicyAsync(postUpsertedPolicyState, sendControlsPolicyData);
}
private async Task UpsertLegacyPolicyAsync<T>(
Guid organizationId,
PolicyType type,
bool enabled,
T? policyData) where T : IPolicyDataModel, new()
{
var existing = await policyRepository.GetByOrganizationIdTypeAsync(organizationId, type);
// Leave Id as default(Guid) for new policies so UpsertAsync routes to CreateAsync;
// pre-assigning an Id causes UpsertAsync to attempt an UPDATE that silently affects 0 rows.
var policy = existing ?? new Policy { OrganizationId = organizationId, Type = type, };
policy.Enabled = enabled;
if (policyData != null)
{
policy.SetDataModel(policyData);
}
policy.RevisionDate = timeProvider.GetUtcNow().UtcDateTime;
await policyRepository.UpsertAsync(policy);
}
public Task<string> ValidateAsync(SavePolicyModel policyRequest, Policy? currentPolicy)
{
var dataModel = policyRequest.PolicyUpdate.GetDataModel<SendControlsPolicyData>();
if (dataModel.AllowedDomains is not null && dataModel.WhoCanAccess != SendWhoCanAccessType.SpecificPeople)
{
return Task.FromResult("Allowed domains can only be set when the required access type is set to specific people");
}
return Task.FromResult(string.Empty);
}
private async Task UpdateSendsByPolicyAsync(Policy postUpsertedPolicyState, SendControlsPolicyData sendControlsPolicyData)
{
var orgSendIds = await sendRepository.GetIdsByOrganizationIdAsync(postUpsertedPolicyState.OrganizationId);
foreach (var sendIdsChunk in orgSendIds.Chunk(50))
{
var enabled = new List<Guid>();
var disabled = new List<Guid>();
var sendsChunk = await sendRepository.GetManyByIdsAsync(sendIdsChunk);
foreach (var send in sendsChunk)
{
if (
// If the policy is disabled then we want to re-enable any Sends that were previously disabled
postUpsertedPolicyState.Enabled &&
(sendControlsPolicyData.DisableSend ||
(sendControlsPolicyData.DisableHideEmail && (send.HideEmail ?? false)) ||
(sendControlsPolicyData.WhoCanAccess == SendWhoCanAccessType.PasswordProtected && send.AuthType != AuthType.Password) ||
(sendControlsPolicyData.WhoCanAccess == SendWhoCanAccessType.SpecificPeople && send.AuthType != AuthType.Email) ||
(sendControlsPolicyData.WhoCanAccess == SendWhoCanAccessType.SpecificPeople && !SendValidationService.SendAllEmailsHaveAllowedDomains(send.Emails, sendControlsPolicyData.AllowedDomains))))
{
disabled.Add(send.Id);
} else
{
enabled.Add(send.Id);
}
}
if (enabled.Count > 0) {
await sendRepository.UpdateManyDisabledAsync(enabled, false);
}
if (disabled.Count > 0)
{
await sendRepository.UpdateManyDisabledAsync(disabled, true);
}
if (sendControlsPolicyData.DeletionDays != null)
{
await sendRepository.UpdateManyDeletionDatesByIdsAsync(sendIdsChunk, sendControlsPolicyData.DeletionDays.GetValueOrDefault(0));
}
}
}
}