mirror of
https://github.com/bitwarden/server.git
synced 2025-07-03 00:52:49 -05:00
Changed all C# control flow block statements to include space between keyword and open paren
This commit is contained in:
@ -26,15 +26,15 @@ namespace Bit.Core.Services
|
||||
IWebHostEnvironment hostingEnvironment,
|
||||
ILogger<AmazonSesMailDeliveryService> logger)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeyId))
|
||||
if (string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeyId))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeyId));
|
||||
}
|
||||
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeySecret))
|
||||
if (string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeySecret))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeySecret));
|
||||
}
|
||||
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.Region))
|
||||
if (string.IsNullOrWhiteSpace(globalSettings.Amazon?.Region))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Amazon.Region));
|
||||
}
|
||||
@ -46,7 +46,7 @@ namespace Bit.Core.Services
|
||||
globalSettings.Amazon.AccessKeySecret, RegionEndpoint.GetBySystemName(globalSettings.Amazon.Region));
|
||||
_source = $"\"{globalSettings.SiteName}\" <{globalSettings.Mail.ReplyToEmail}>";
|
||||
_senderTag = $"Server_{globalSettings.ProjectName}";
|
||||
if(!string.IsNullOrWhiteSpace(_globalSettings.Mail.AmazonConfigSetName))
|
||||
if (!string.IsNullOrWhiteSpace(_globalSettings.Mail.AmazonConfigSetName))
|
||||
{
|
||||
_configSetName = _globalSettings.Mail.AmazonConfigSetName;
|
||||
}
|
||||
@ -91,12 +91,12 @@ namespace Bit.Core.Services
|
||||
}
|
||||
};
|
||||
|
||||
if(message.BccEmails?.Any() ?? false)
|
||||
if (message.BccEmails?.Any() ?? false)
|
||||
{
|
||||
request.Destination.BccAddresses = message.BccEmails.ToList();
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(message.Category))
|
||||
if (!string.IsNullOrWhiteSpace(message.Category))
|
||||
{
|
||||
request.Tags.Add(new MessageTag { Name = "Category", Value = message.Category });
|
||||
}
|
||||
@ -105,7 +105,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
await SendAsync(request, false);
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogWarning(e, "Failed to send email. Re-retying...");
|
||||
await SendAsync(request, true);
|
||||
@ -115,7 +115,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task SendAsync(SendEmailRequest request, bool retry)
|
||||
{
|
||||
if(retry)
|
||||
if (retry)
|
||||
{
|
||||
// wait and try again
|
||||
await Task.Delay(2000);
|
||||
|
@ -16,15 +16,15 @@ namespace Bit.Core.Services
|
||||
public AmazonSqsBlockIpService(
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeyId))
|
||||
if (string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeyId))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeyId));
|
||||
}
|
||||
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeySecret))
|
||||
if (string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeySecret))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeySecret));
|
||||
}
|
||||
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.Region))
|
||||
if (string.IsNullOrWhiteSpace(globalSettings.Amazon?.Region))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Amazon.Region));
|
||||
}
|
||||
@ -40,7 +40,7 @@ namespace Bit.Core.Services
|
||||
public async Task BlockIpAsync(string ipAddress, bool permanentBlock)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if(_lastBlock != null && _lastBlock.Item1 == ipAddress && _lastBlock.Item2 == permanentBlock &&
|
||||
if (_lastBlock != null && _lastBlock.Item1 == ipAddress && _lastBlock.Item2 == permanentBlock &&
|
||||
(now - _lastBlock.Item3) < TimeSpan.FromMinutes(1))
|
||||
{
|
||||
// Already blocked this IP recently.
|
||||
@ -49,7 +49,7 @@ namespace Bit.Core.Services
|
||||
|
||||
_lastBlock = new Tuple<string, bool, DateTime>(ipAddress, permanentBlock, now);
|
||||
await _client.SendMessageAsync(_blockIpQueueUrl, ipAddress);
|
||||
if(!permanentBlock)
|
||||
if (!permanentBlock)
|
||||
{
|
||||
await _client.SendMessageAsync(_unblockIpQueueUrl, ipAddress);
|
||||
}
|
||||
@ -57,7 +57,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task InitAsync()
|
||||
{
|
||||
if(_didInit)
|
||||
if (_didInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace Bit.Core.Services
|
||||
public async Task<AppleReceiptStatus> GetVerifiedReceiptStatusAsync(string receiptData)
|
||||
{
|
||||
var receiptStatus = await GetReceiptStatusAsync(receiptData);
|
||||
if(receiptStatus?.Status != 0)
|
||||
if (receiptStatus?.Status != 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -51,7 +51,7 @@ namespace Bit.Core.Services
|
||||
receiptStatus.GetLastTransactionId() != null;
|
||||
var validTransaction = receiptStatus.GetLastExpiresDate()
|
||||
.GetValueOrDefault(DateTime.MinValue) > DateTime.UtcNow;
|
||||
if(validEnvironment && validProductBundle && validProduct && validIds && validTransaction)
|
||||
if (validEnvironment && validProductBundle && validProduct && validIds && validTransaction)
|
||||
{
|
||||
return receiptStatus;
|
||||
}
|
||||
@ -61,7 +61,7 @@ namespace Bit.Core.Services
|
||||
public async Task SaveReceiptAsync(AppleReceiptStatus receiptStatus, Guid userId)
|
||||
{
|
||||
var originalTransactionId = receiptStatus.GetOriginalTransactionId();
|
||||
if(string.IsNullOrWhiteSpace(originalTransactionId))
|
||||
if (string.IsNullOrWhiteSpace(originalTransactionId))
|
||||
{
|
||||
throw new Exception("OriginalTransactionId is null");
|
||||
}
|
||||
@ -76,7 +76,7 @@ namespace Bit.Core.Services
|
||||
public async Task<Tuple<string, Guid?>> GetReceiptAsync(string originalTransactionId)
|
||||
{
|
||||
var receipt = await _metaDataRespository.GetAsync("AppleReceipt", originalTransactionId);
|
||||
if(receipt == null)
|
||||
if (receipt == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -89,7 +89,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
if(attempt > 4)
|
||||
if (attempt > 4)
|
||||
{
|
||||
throw new Exception("Failed verifying Apple IAP after too many attempts. Last attempt status: " +
|
||||
lastReceiptStatus?.Status ?? "null");
|
||||
@ -100,15 +100,15 @@ namespace Bit.Core.Services
|
||||
new JProperty("password", _globalSettings.AppleIap.Password)).ToString();
|
||||
|
||||
var response = await _httpClient.PostAsync(url, new StringContent(json));
|
||||
if(response.IsSuccessStatusCode)
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseJson = await response.Content.ReadAsStringAsync();
|
||||
var receiptStatus = JsonConvert.DeserializeObject<AppleReceiptStatus>(responseJson);
|
||||
if(receiptStatus.Status == 21007)
|
||||
if (receiptStatus.Status == 21007)
|
||||
{
|
||||
return await GetReceiptStatusAsync(receiptData, false, attempt + 1, receiptStatus);
|
||||
}
|
||||
else if(receiptStatus.Status == 21005)
|
||||
else if (receiptStatus.Status == 21005)
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
return await GetReceiptStatusAsync(receiptData, prod, attempt + 1, receiptStatus);
|
||||
@ -116,7 +116,7 @@ namespace Bit.Core.Services
|
||||
return receiptStatus;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogWarning(e, "Error verifying Apple IAP receipt.");
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace Bit.Core.Services
|
||||
await InitAsync();
|
||||
var blob = _attachmentsContainer.GetBlockBlobReference($"{cipher.Id}/{attachmentId}");
|
||||
blob.Metadata.Add("cipherId", cipher.Id.ToString());
|
||||
if(cipher.UserId.HasValue)
|
||||
if (cipher.UserId.HasValue)
|
||||
{
|
||||
blob.Metadata.Add("userId", cipher.UserId.Value.ToString());
|
||||
}
|
||||
@ -52,13 +52,13 @@ namespace Bit.Core.Services
|
||||
{
|
||||
await InitAsync();
|
||||
var source = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}");
|
||||
if(!(await source.ExistsAsync()))
|
||||
if (!(await source.ExistsAsync()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dest = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/{attachmentId}");
|
||||
if(!(await dest.ExistsAsync()))
|
||||
if (!(await dest.ExistsAsync()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -78,7 +78,7 @@ namespace Bit.Core.Services
|
||||
await source.DeleteIfExistsAsync();
|
||||
|
||||
var original = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{attachmentId}");
|
||||
if(!(await original.ExistsAsync()))
|
||||
if (!(await original.ExistsAsync()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -103,17 +103,17 @@ namespace Bit.Core.Services
|
||||
var segment = await _attachmentsContainer.ListBlobsSegmentedAsync($"temp/{cipherId}", true,
|
||||
BlobListingDetails.None, 100, null, null, null);
|
||||
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
foreach(var blob in segment.Results)
|
||||
foreach (var blob in segment.Results)
|
||||
{
|
||||
if(blob is CloudBlockBlob blockBlob)
|
||||
if (blob is CloudBlockBlob blockBlob)
|
||||
{
|
||||
await blockBlob.DeleteIfExistsAsync();
|
||||
}
|
||||
}
|
||||
|
||||
if(segment.ContinuationToken == null)
|
||||
if (segment.ContinuationToken == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -128,17 +128,17 @@ namespace Bit.Core.Services
|
||||
var segment = await _attachmentsContainer.ListBlobsSegmentedAsync(cipherId.ToString(), true,
|
||||
BlobListingDetails.None, 100, null, null, null);
|
||||
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
foreach(var blob in segment.Results)
|
||||
foreach (var blob in segment.Results)
|
||||
{
|
||||
if(blob is CloudBlockBlob blockBlob)
|
||||
if (blob is CloudBlockBlob blockBlob)
|
||||
{
|
||||
await blockBlob.DeleteIfExistsAsync();
|
||||
}
|
||||
}
|
||||
|
||||
if(segment.ContinuationToken == null)
|
||||
if (segment.ContinuationToken == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -159,7 +159,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task InitAsync()
|
||||
{
|
||||
if(_attachmentsContainer == null)
|
||||
if (_attachmentsContainer == null)
|
||||
{
|
||||
_attachmentsContainer = _blobClient.GetContainerReference(AttchmentContainerName);
|
||||
await _attachmentsContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.Core.Services
|
||||
public async Task BlockIpAsync(string ipAddress, bool permanentBlock)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if(_lastBlock != null && _lastBlock.Item1 == ipAddress && _lastBlock.Item2 == permanentBlock &&
|
||||
if (_lastBlock != null && _lastBlock.Item1 == ipAddress && _lastBlock.Item2 == permanentBlock &&
|
||||
(now - _lastBlock.Item3) < TimeSpan.FromMinutes(1))
|
||||
{
|
||||
// Already blocked this IP recently.
|
||||
@ -29,7 +29,7 @@ namespace Bit.Core.Services
|
||||
|
||||
_lastBlock = new Tuple<string, bool, DateTime>(ipAddress, permanentBlock, now);
|
||||
await _blockIpQueueClient.SendMessageAsync(ipAddress);
|
||||
if(!permanentBlock)
|
||||
if (!permanentBlock)
|
||||
{
|
||||
await _unblockIpQueueClient.SendMessageAsync(ipAddress, new TimeSpan(0, 15, 0));
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
var message = new SyncCipherPushNotification
|
||||
{
|
||||
@ -59,7 +59,7 @@ namespace Bit.Core.Services
|
||||
|
||||
await SendMessageAsync(type, message, true);
|
||||
}
|
||||
else if(cipher.UserId.HasValue)
|
||||
else if (cipher.UserId.HasValue)
|
||||
{
|
||||
var message = new SyncCipherPushNotification
|
||||
{
|
||||
@ -145,7 +145,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
||||
{
|
||||
if(!excludeCurrentContext)
|
||||
if (!excludeCurrentContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ namespace Bit.Core.Services
|
||||
protected async Task SendAsync(HttpMethod method, string path, object requestModel = null)
|
||||
{
|
||||
var tokenStateResponse = await HandleTokenStateAsync();
|
||||
if(!tokenStateResponse)
|
||||
if (!tokenStateResponse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -70,7 +70,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var response = await Client.SendAsync(message);
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(12334, e, "Failed to send to {0}.", message.RequestUri.ToString());
|
||||
}
|
||||
@ -78,13 +78,13 @@ namespace Bit.Core.Services
|
||||
|
||||
protected async Task<bool> HandleTokenStateAsync()
|
||||
{
|
||||
if(_nextAuthAttempt.HasValue && DateTime.UtcNow > _nextAuthAttempt.Value)
|
||||
if (_nextAuthAttempt.HasValue && DateTime.UtcNow > _nextAuthAttempt.Value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_nextAuthAttempt = null;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(AccessToken) && !TokenNeedsRefresh())
|
||||
if (!string.IsNullOrWhiteSpace(AccessToken) && !TokenNeedsRefresh())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -107,19 +107,19 @@ namespace Bit.Core.Services
|
||||
{
|
||||
response = await IdentityClient.SendAsync(requestMessage);
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(12339, e, "Unable to authenticate with identity server.");
|
||||
}
|
||||
|
||||
if(response == null)
|
||||
if (response == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!response.IsSuccessStatusCode)
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
if(response.StatusCode == HttpStatusCode.BadRequest)
|
||||
if (response.StatusCode == HttpStatusCode.BadRequest)
|
||||
{
|
||||
_nextAuthAttempt = DateTime.UtcNow.AddDays(1);
|
||||
}
|
||||
@ -143,7 +143,7 @@ namespace Bit.Core.Services
|
||||
public TokenHttpRequestMessage(object requestObject, string token)
|
||||
: this(token)
|
||||
{
|
||||
if(requestObject != null)
|
||||
if (requestObject != null)
|
||||
{
|
||||
var stringContent = JsonConvert.SerializeObject(requestObject);
|
||||
Content = new StringContent(stringContent, Encoding.UTF8, "application/json");
|
||||
@ -155,7 +155,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var decoded = DecodeToken();
|
||||
var exp = decoded?["exp"];
|
||||
if(exp == null)
|
||||
if (exp == null)
|
||||
{
|
||||
throw new InvalidOperationException("No exp in token.");
|
||||
}
|
||||
@ -166,24 +166,24 @@ namespace Bit.Core.Services
|
||||
|
||||
protected JObject DecodeToken()
|
||||
{
|
||||
if(_decodedToken != null)
|
||||
if (_decodedToken != null)
|
||||
{
|
||||
return _decodedToken;
|
||||
}
|
||||
|
||||
if(AccessToken == null)
|
||||
if (AccessToken == null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(AccessToken)} not found.");
|
||||
}
|
||||
|
||||
var parts = AccessToken.Split('.');
|
||||
if(parts.Length != 3)
|
||||
if (parts.Length != 3)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts");
|
||||
}
|
||||
|
||||
var decodedBytes = CoreHelpers.Base64UrlDecode(parts[1]);
|
||||
if(decodedBytes == null || decodedBytes.Length < 1)
|
||||
if (decodedBytes == null || decodedBytes.Length < 1)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts");
|
||||
}
|
||||
|
@ -60,16 +60,16 @@ namespace Bit.Core.Services
|
||||
public async Task SaveAsync(Cipher cipher, Guid savingUserId, IEnumerable<Guid> collectionIds = null,
|
||||
bool skipPermissionCheck = false, bool limitCollectionScope = true)
|
||||
{
|
||||
if(!skipPermissionCheck && !(await UserCanEditAsync(cipher, savingUserId)))
|
||||
if (!skipPermissionCheck && !(await UserCanEditAsync(cipher, savingUserId)))
|
||||
{
|
||||
throw new BadRequestException("You do not have permissions to edit this.");
|
||||
}
|
||||
|
||||
if(cipher.Id == default(Guid))
|
||||
if (cipher.Id == default(Guid))
|
||||
{
|
||||
if(cipher.OrganizationId.HasValue && collectionIds != null)
|
||||
if (cipher.OrganizationId.HasValue && collectionIds != null)
|
||||
{
|
||||
if(limitCollectionScope)
|
||||
if (limitCollectionScope)
|
||||
{
|
||||
// Set user ID to limit scope of collection ids in the create sproc
|
||||
cipher.UserId = savingUserId;
|
||||
@ -87,7 +87,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
if(collectionIds != null)
|
||||
if (collectionIds != null)
|
||||
{
|
||||
throw new ArgumentException("Cannot create cipher with collection ids at the same time.");
|
||||
}
|
||||
@ -103,15 +103,15 @@ namespace Bit.Core.Services
|
||||
public async Task SaveDetailsAsync(CipherDetails cipher, Guid savingUserId,
|
||||
IEnumerable<Guid> collectionIds = null, bool skipPermissionCheck = false)
|
||||
{
|
||||
if(!skipPermissionCheck && !(await UserCanEditAsync(cipher, savingUserId)))
|
||||
if (!skipPermissionCheck && !(await UserCanEditAsync(cipher, savingUserId)))
|
||||
{
|
||||
throw new BadRequestException("You do not have permissions to edit this.");
|
||||
}
|
||||
|
||||
cipher.UserId = savingUserId;
|
||||
if(cipher.Id == default(Guid))
|
||||
if (cipher.Id == default(Guid))
|
||||
{
|
||||
if(cipher.OrganizationId.HasValue && collectionIds != null)
|
||||
if (cipher.OrganizationId.HasValue && collectionIds != null)
|
||||
{
|
||||
await _cipherRepository.CreateAsync(cipher, collectionIds);
|
||||
}
|
||||
@ -121,7 +121,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_Created);
|
||||
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(cipher.OrganizationId.Value);
|
||||
cipher.OrganizationUseTotp = org.UseTotp;
|
||||
@ -132,7 +132,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
if(collectionIds != null)
|
||||
if (collectionIds != null)
|
||||
{
|
||||
throw new ArgumentException("Cannot create cipher with collection ids at the same time.");
|
||||
}
|
||||
@ -148,26 +148,26 @@ namespace Bit.Core.Services
|
||||
public async Task CreateAttachmentAsync(Cipher cipher, Stream stream, string fileName, string key,
|
||||
long requestLength, Guid savingUserId, bool orgAdmin = false)
|
||||
{
|
||||
if(!orgAdmin && !(await UserCanEditAsync(cipher, savingUserId)))
|
||||
if (!orgAdmin && !(await UserCanEditAsync(cipher, savingUserId)))
|
||||
{
|
||||
throw new BadRequestException("You do not have permissions to edit this.");
|
||||
}
|
||||
|
||||
if(requestLength < 1)
|
||||
if (requestLength < 1)
|
||||
{
|
||||
throw new BadRequestException("No data to attach.");
|
||||
}
|
||||
|
||||
var storageBytesRemaining = 0L;
|
||||
if(cipher.UserId.HasValue)
|
||||
if (cipher.UserId.HasValue)
|
||||
{
|
||||
var user = await _userRepository.GetByIdAsync(cipher.UserId.Value);
|
||||
if(!(await _userService.CanAccessPremium(user)))
|
||||
if (!(await _userService.CanAccessPremium(user)))
|
||||
{
|
||||
throw new BadRequestException("You must have premium status to use attachments.");
|
||||
}
|
||||
|
||||
if(user.Premium)
|
||||
if (user.Premium)
|
||||
{
|
||||
storageBytesRemaining = user.StorageBytesRemaining();
|
||||
}
|
||||
@ -179,10 +179,10 @@ namespace Bit.Core.Services
|
||||
_globalSettings.SelfHosted ? (short)10240 : (short)1);
|
||||
}
|
||||
}
|
||||
else if(cipher.OrganizationId.HasValue)
|
||||
else if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(cipher.OrganizationId.Value);
|
||||
if(!org.MaxStorageGb.HasValue)
|
||||
if (!org.MaxStorageGb.HasValue)
|
||||
{
|
||||
throw new BadRequestException("This organization cannot use attachments.");
|
||||
}
|
||||
@ -190,7 +190,7 @@ namespace Bit.Core.Services
|
||||
storageBytesRemaining = org.StorageBytesRemaining();
|
||||
}
|
||||
|
||||
if(storageBytesRemaining < requestLength)
|
||||
if (storageBytesRemaining < requestLength)
|
||||
{
|
||||
throw new BadRequestException("Not enough storage available.");
|
||||
}
|
||||
@ -236,29 +236,29 @@ namespace Bit.Core.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
if(requestLength < 1)
|
||||
if (requestLength < 1)
|
||||
{
|
||||
throw new BadRequestException("No data to attach.");
|
||||
}
|
||||
|
||||
if(cipher.Id == default(Guid))
|
||||
if (cipher.Id == default(Guid))
|
||||
{
|
||||
throw new BadRequestException(nameof(cipher.Id));
|
||||
}
|
||||
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("Cipher belongs to an organization already.");
|
||||
}
|
||||
|
||||
var org = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if(org == null || !org.MaxStorageGb.HasValue)
|
||||
if (org == null || !org.MaxStorageGb.HasValue)
|
||||
{
|
||||
throw new BadRequestException("This organization cannot use attachments.");
|
||||
}
|
||||
|
||||
var storageBytesRemaining = org.StorageBytesRemaining();
|
||||
if(storageBytesRemaining < requestLength)
|
||||
if (storageBytesRemaining < requestLength)
|
||||
{
|
||||
throw new BadRequestException("Not enough storage available for this organization.");
|
||||
}
|
||||
@ -275,7 +275,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task DeleteAsync(Cipher cipher, Guid deletingUserId, bool orgAdmin = false)
|
||||
{
|
||||
if(!orgAdmin && !(await UserCanEditAsync(cipher, deletingUserId)))
|
||||
if (!orgAdmin && !(await UserCanEditAsync(cipher, deletingUserId)))
|
||||
{
|
||||
throw new BadRequestException("You do not have permissions to delete this.");
|
||||
}
|
||||
@ -298,7 +298,7 @@ namespace Bit.Core.Services
|
||||
|
||||
var events = deletingCiphers.Select(c =>
|
||||
new Tuple<Cipher, EventType, DateTime?>(c, EventType.Cipher_Deleted, null));
|
||||
foreach(var eventsBatch in events.Batch(100))
|
||||
foreach (var eventsBatch in events.Batch(100))
|
||||
{
|
||||
await _eventService.LogCipherEventsAsync(eventsBatch);
|
||||
}
|
||||
@ -310,12 +310,12 @@ namespace Bit.Core.Services
|
||||
public async Task DeleteAttachmentAsync(Cipher cipher, string attachmentId, Guid deletingUserId,
|
||||
bool orgAdmin = false)
|
||||
{
|
||||
if(!orgAdmin && !(await UserCanEditAsync(cipher, deletingUserId)))
|
||||
if (!orgAdmin && !(await UserCanEditAsync(cipher, deletingUserId)))
|
||||
{
|
||||
throw new BadRequestException("You do not have permissions to delete this.");
|
||||
}
|
||||
|
||||
if(!cipher.ContainsAttachment(attachmentId))
|
||||
if (!cipher.ContainsAttachment(attachmentId))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -332,7 +332,7 @@ namespace Bit.Core.Services
|
||||
public async Task PurgeAsync(Guid organizationId)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if(org == null)
|
||||
if (org == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -342,10 +342,10 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task MoveManyAsync(IEnumerable<Guid> cipherIds, Guid? destinationFolderId, Guid movingUserId)
|
||||
{
|
||||
if(destinationFolderId.HasValue)
|
||||
if (destinationFolderId.HasValue)
|
||||
{
|
||||
var folder = await _folderRepository.GetByIdAsync(destinationFolderId.Value);
|
||||
if(folder == null || folder.UserId != movingUserId)
|
||||
if (folder == null || folder.UserId != movingUserId)
|
||||
{
|
||||
throw new BadRequestException("Invalid folder.");
|
||||
}
|
||||
@ -358,7 +358,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SaveFolderAsync(Folder folder)
|
||||
{
|
||||
if(folder.Id == default(Guid))
|
||||
if (folder.Id == default(Guid))
|
||||
{
|
||||
await _folderRepository.CreateAsync(folder);
|
||||
|
||||
@ -394,29 +394,29 @@ namespace Bit.Core.Services
|
||||
|
||||
try
|
||||
{
|
||||
if(cipher.Id == default(Guid))
|
||||
if (cipher.Id == default(Guid))
|
||||
{
|
||||
throw new BadRequestException(nameof(cipher.Id));
|
||||
}
|
||||
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("Already belongs to an organization.");
|
||||
}
|
||||
|
||||
if(!cipher.UserId.HasValue || cipher.UserId.Value != sharingUserId)
|
||||
if (!cipher.UserId.HasValue || cipher.UserId.Value != sharingUserId)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var org = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if(hasAttachments && !org.MaxStorageGb.HasValue)
|
||||
if (hasAttachments && !org.MaxStorageGb.HasValue)
|
||||
{
|
||||
throw new BadRequestException("This organization cannot use attachments.");
|
||||
}
|
||||
|
||||
var storageAdjustment = attachments?.Sum(a => a.Value.Size) ?? 0;
|
||||
if(org.StorageBytesRemaining() < storageAdjustment)
|
||||
if (org.StorageBytesRemaining() < storageAdjustment)
|
||||
{
|
||||
throw new BadRequestException("Not enough storage available for this organization.");
|
||||
}
|
||||
@ -425,7 +425,7 @@ namespace Bit.Core.Services
|
||||
cipher.UserId = sharingUserId;
|
||||
cipher.OrganizationId = organizationId;
|
||||
cipher.RevisionDate = DateTime.UtcNow;
|
||||
if(!await _cipherRepository.ReplaceAsync(cipher, collectionIds))
|
||||
if (!await _cipherRepository.ReplaceAsync(cipher, collectionIds))
|
||||
{
|
||||
throw new BadRequestException("Unable to save.");
|
||||
}
|
||||
@ -433,10 +433,10 @@ namespace Bit.Core.Services
|
||||
updatedCipher = true;
|
||||
await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_Shared);
|
||||
|
||||
if(hasOldAttachments)
|
||||
if (hasOldAttachments)
|
||||
{
|
||||
// migrate old attachments
|
||||
foreach(var attachment in attachments.Where(a => a.Key == null))
|
||||
foreach (var attachment in attachments.Where(a => a.Key == null))
|
||||
{
|
||||
await _attachmentStorageService.StartShareAttachmentAsync(cipher.Id, organizationId,
|
||||
attachment.Key);
|
||||
@ -453,23 +453,23 @@ namespace Bit.Core.Services
|
||||
catch
|
||||
{
|
||||
// roll everything back
|
||||
if(updatedCipher)
|
||||
if (updatedCipher)
|
||||
{
|
||||
await _cipherRepository.ReplaceAsync(originalCipher);
|
||||
}
|
||||
|
||||
if(!hasOldAttachments || !migratedAttachments)
|
||||
if (!hasOldAttachments || !migratedAttachments)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
if(updatedCipher)
|
||||
if (updatedCipher)
|
||||
{
|
||||
await _userRepository.UpdateStorageAsync(sharingUserId);
|
||||
await _organizationRepository.UpdateStorageAsync(organizationId);
|
||||
}
|
||||
|
||||
foreach(var attachment in attachments.Where(a => a.Key == null))
|
||||
foreach (var attachment in attachments.Where(a => a.Key == null))
|
||||
{
|
||||
await _attachmentStorageService.RollbackShareAttachmentAsync(cipher.Id, organizationId,
|
||||
attachment.Key);
|
||||
@ -484,19 +484,19 @@ namespace Bit.Core.Services
|
||||
IEnumerable<Guid> collectionIds, Guid sharingUserId)
|
||||
{
|
||||
var cipherIds = new List<Guid>();
|
||||
foreach(var cipher in ciphers)
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
if(cipher.Id == default(Guid))
|
||||
if (cipher.Id == default(Guid))
|
||||
{
|
||||
throw new BadRequestException("All ciphers must already exist.");
|
||||
}
|
||||
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("One or more ciphers already belong to an organization.");
|
||||
}
|
||||
|
||||
if(!cipher.UserId.HasValue || cipher.UserId.Value != sharingUserId)
|
||||
if (!cipher.UserId.HasValue || cipher.UserId.Value != sharingUserId)
|
||||
{
|
||||
throw new BadRequestException("One or more ciphers do not belong to you.");
|
||||
}
|
||||
@ -513,7 +513,7 @@ namespace Bit.Core.Services
|
||||
|
||||
var events = ciphers.Select(c =>
|
||||
new Tuple<Cipher, EventType, DateTime?>(c, EventType.Cipher_Shared, null));
|
||||
foreach(var eventsBatch in events.Batch(100))
|
||||
foreach (var eventsBatch in events.Batch(100))
|
||||
{
|
||||
await _eventService.LogCipherEventsAsync(eventsBatch);
|
||||
}
|
||||
@ -525,12 +525,12 @@ namespace Bit.Core.Services
|
||||
public async Task SaveCollectionsAsync(Cipher cipher, IEnumerable<Guid> collectionIds, Guid savingUserId,
|
||||
bool orgAdmin)
|
||||
{
|
||||
if(cipher.Id == default(Guid))
|
||||
if (cipher.Id == default(Guid))
|
||||
{
|
||||
throw new BadRequestException(nameof(cipher.Id));
|
||||
}
|
||||
|
||||
if(!cipher.OrganizationId.HasValue)
|
||||
if (!cipher.OrganizationId.HasValue)
|
||||
{
|
||||
throw new BadRequestException("Cipher must belong to an organization.");
|
||||
}
|
||||
@ -539,14 +539,14 @@ namespace Bit.Core.Services
|
||||
|
||||
// The sprocs will validate that all collections belong to this org/user and that they have
|
||||
// proper write permissions.
|
||||
if(orgAdmin)
|
||||
if (orgAdmin)
|
||||
{
|
||||
await _collectionCipherRepository.UpdateCollectionsForAdminAsync(cipher.Id,
|
||||
cipher.OrganizationId.Value, collectionIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!(await UserCanEditAsync(cipher, savingUserId)))
|
||||
if (!(await UserCanEditAsync(cipher, savingUserId)))
|
||||
{
|
||||
throw new BadRequestException("You do not have permissions to edit this.");
|
||||
}
|
||||
@ -564,29 +564,29 @@ namespace Bit.Core.Services
|
||||
List<CipherDetails> ciphers,
|
||||
IEnumerable<KeyValuePair<int, int>> folderRelationships)
|
||||
{
|
||||
foreach(var cipher in ciphers)
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.SetNewId();
|
||||
|
||||
if(cipher.UserId.HasValue && cipher.Favorite)
|
||||
if (cipher.UserId.HasValue && cipher.Favorite)
|
||||
{
|
||||
cipher.Favorites = $"{{\"{cipher.UserId.ToString().ToUpperInvariant()}\":\"true\"}}";
|
||||
}
|
||||
}
|
||||
|
||||
// Init. ids for folders
|
||||
foreach(var folder in folders)
|
||||
foreach (var folder in folders)
|
||||
{
|
||||
folder.SetNewId();
|
||||
}
|
||||
|
||||
// Create the folder associations based on the newly created folder ids
|
||||
foreach(var relationship in folderRelationships)
|
||||
foreach (var relationship in folderRelationships)
|
||||
{
|
||||
var cipher = ciphers.ElementAtOrDefault(relationship.Key);
|
||||
var folder = folders.ElementAtOrDefault(relationship.Value);
|
||||
|
||||
if(cipher == null || folder == null)
|
||||
if (cipher == null || folder == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -600,7 +600,7 @@ namespace Bit.Core.Services
|
||||
|
||||
// push
|
||||
var userId = folders.FirstOrDefault()?.UserId ?? ciphers.FirstOrDefault()?.UserId;
|
||||
if(userId.HasValue)
|
||||
if (userId.HasValue)
|
||||
{
|
||||
await _pushService.PushSyncVaultAsync(userId.Value);
|
||||
}
|
||||
@ -612,13 +612,13 @@ namespace Bit.Core.Services
|
||||
IEnumerable<KeyValuePair<int, int>> collectionRelationships,
|
||||
Guid importingUserId)
|
||||
{
|
||||
if(collections.Count > 0)
|
||||
if (collections.Count > 0)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(collections[0].OrganizationId);
|
||||
if(org != null && org.MaxCollections.HasValue)
|
||||
if (org != null && org.MaxCollections.HasValue)
|
||||
{
|
||||
var collectionCount = await _collectionRepository.GetCountByOrganizationIdAsync(org.Id);
|
||||
if(org.MaxCollections.Value < (collectionCount + collections.Count))
|
||||
if (org.MaxCollections.Value < (collectionCount + collections.Count))
|
||||
{
|
||||
throw new BadRequestException("This organization can only have a maximum of " +
|
||||
$"{org.MaxCollections.Value} collections.");
|
||||
@ -627,25 +627,25 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
// Init. ids for ciphers
|
||||
foreach(var cipher in ciphers)
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.SetNewId();
|
||||
}
|
||||
|
||||
// Init. ids for collections
|
||||
foreach(var collection in collections)
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
collection.SetNewId();
|
||||
}
|
||||
|
||||
// Create associations based on the newly assigned ids
|
||||
var collectionCiphers = new List<CollectionCipher>();
|
||||
foreach(var relationship in collectionRelationships)
|
||||
foreach (var relationship in collectionRelationships)
|
||||
{
|
||||
var cipher = ciphers.ElementAtOrDefault(relationship.Key);
|
||||
var collection = collections.ElementAtOrDefault(relationship.Value);
|
||||
|
||||
if(cipher == null || collection == null)
|
||||
if (cipher == null || collection == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -666,7 +666,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task<bool> UserCanEditAsync(Cipher cipher, Guid userId)
|
||||
{
|
||||
if(!cipher.OrganizationId.HasValue && cipher.UserId.HasValue && cipher.UserId.Value == userId)
|
||||
if (!cipher.OrganizationId.HasValue && cipher.UserId.HasValue && cipher.UserId.Value == userId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -37,24 +37,24 @@ namespace Bit.Core.Services
|
||||
Guid? assignUserId = null)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
|
||||
if(org == null)
|
||||
if (org == null)
|
||||
{
|
||||
throw new BadRequestException("Organization not found");
|
||||
}
|
||||
|
||||
if(collection.Id == default(Guid))
|
||||
if (collection.Id == default(Guid))
|
||||
{
|
||||
if(org.MaxCollections.HasValue)
|
||||
if (org.MaxCollections.HasValue)
|
||||
{
|
||||
var collectionCount = await _collectionRepository.GetCountByOrganizationIdAsync(org.Id);
|
||||
if(org.MaxCollections.Value <= collectionCount)
|
||||
if (org.MaxCollections.Value <= collectionCount)
|
||||
{
|
||||
throw new BadRequestException("You have reached the maximum number of collections " +
|
||||
$"({org.MaxCollections.Value}) for this organization.");
|
||||
}
|
||||
}
|
||||
|
||||
if(groups == null || !org.UseGroups)
|
||||
if (groups == null || !org.UseGroups)
|
||||
{
|
||||
await _collectionRepository.CreateAsync(collection);
|
||||
}
|
||||
@ -64,10 +64,10 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
// Assign a user to the newly created collection.
|
||||
if(assignUserId.HasValue)
|
||||
if (assignUserId.HasValue)
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, assignUserId.Value);
|
||||
if(orgUser != null && orgUser.Status == Enums.OrganizationUserStatusType.Confirmed)
|
||||
if (orgUser != null && orgUser.Status == Enums.OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
await _collectionRepository.UpdateUsersAsync(collection.Id,
|
||||
new List<SelectionReadOnly> {
|
||||
@ -79,7 +79,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!org.UseGroups)
|
||||
if (!org.UseGroups)
|
||||
{
|
||||
await _collectionRepository.ReplaceAsync(collection);
|
||||
}
|
||||
@ -101,7 +101,7 @@ namespace Bit.Core.Services
|
||||
public async Task DeleteUserAsync(Collection collection, Guid organizationUserId)
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByIdAsync(organizationUserId);
|
||||
if(orgUser == null || orgUser.OrganizationId != collection.OrganizationId)
|
||||
if (orgUser == null || orgUser.OrganizationId != collection.OrganizationId)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SaveAsync(Device device)
|
||||
{
|
||||
if(device.Id == default(Guid))
|
||||
if (device.Id == default(Guid))
|
||||
{
|
||||
await _deviceRepository.CreateAsync(device);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ namespace Bit.Core.Services
|
||||
Date = DateTime.UtcNow
|
||||
});
|
||||
|
||||
if(orgEvents.Any())
|
||||
if (orgEvents.Any())
|
||||
{
|
||||
events.AddRange(orgEvents);
|
||||
await _eventWriteService.CreateManyAsync(events);
|
||||
@ -70,7 +70,7 @@ namespace Bit.Core.Services
|
||||
public async Task LogCipherEventAsync(Cipher cipher, EventType type, DateTime? date = null)
|
||||
{
|
||||
var e = await BuildCipherEventMessageAsync(cipher, type, date);
|
||||
if(e != null)
|
||||
if (e != null)
|
||||
{
|
||||
await _eventWriteService.CreateAsync(e);
|
||||
}
|
||||
@ -79,10 +79,10 @@ namespace Bit.Core.Services
|
||||
public async Task LogCipherEventsAsync(IEnumerable<Tuple<Cipher, EventType, DateTime?>> events)
|
||||
{
|
||||
var cipherEvents = new List<IEvent>();
|
||||
foreach(var ev in events)
|
||||
foreach (var ev in events)
|
||||
{
|
||||
var e = await BuildCipherEventMessageAsync(ev.Item1, ev.Item2, ev.Item3);
|
||||
if(e != null)
|
||||
if (e != null)
|
||||
{
|
||||
cipherEvents.Add(e);
|
||||
}
|
||||
@ -93,15 +93,15 @@ namespace Bit.Core.Services
|
||||
private async Task<EventMessage> BuildCipherEventMessageAsync(Cipher cipher, EventType type, DateTime? date = null)
|
||||
{
|
||||
// Only logging organization cipher events for now.
|
||||
if(!cipher.OrganizationId.HasValue || (!_currentContext?.UserId.HasValue ?? true))
|
||||
if (!cipher.OrganizationId.HasValue || (!_currentContext?.UserId.HasValue ?? true))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
||||
if(!CanUseEvents(orgAbilities, cipher.OrganizationId.Value))
|
||||
if (!CanUseEvents(orgAbilities, cipher.OrganizationId.Value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -121,7 +121,7 @@ namespace Bit.Core.Services
|
||||
public async Task LogCollectionEventAsync(Collection collection, EventType type, DateTime? date = null)
|
||||
{
|
||||
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
||||
if(!CanUseEvents(orgAbilities, collection.OrganizationId))
|
||||
if (!CanUseEvents(orgAbilities, collection.OrganizationId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -140,7 +140,7 @@ namespace Bit.Core.Services
|
||||
public async Task LogGroupEventAsync(Group group, EventType type, DateTime? date = null)
|
||||
{
|
||||
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
||||
if(!CanUseEvents(orgAbilities, group.OrganizationId))
|
||||
if (!CanUseEvents(orgAbilities, group.OrganizationId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -159,7 +159,7 @@ namespace Bit.Core.Services
|
||||
public async Task LogPolicyEventAsync(Policy policy, EventType type, DateTime? date = null)
|
||||
{
|
||||
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
||||
if(!CanUseEvents(orgAbilities, policy.OrganizationId))
|
||||
if (!CanUseEvents(orgAbilities, policy.OrganizationId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -179,7 +179,7 @@ namespace Bit.Core.Services
|
||||
DateTime? date = null)
|
||||
{
|
||||
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
||||
if(!CanUseEvents(orgAbilities, organizationUser.OrganizationId))
|
||||
if (!CanUseEvents(orgAbilities, organizationUser.OrganizationId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -198,7 +198,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task LogOrganizationEventAsync(Organization organization, EventType type, DateTime? date = null)
|
||||
{
|
||||
if(!organization.Enabled || !organization.UseEvents)
|
||||
if (!organization.Enabled || !organization.UseEvents)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -30,21 +30,21 @@ namespace Bit.Core.Services
|
||||
public async Task SaveAsync(Group group, IEnumerable<SelectionReadOnly> collections = null)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(group.OrganizationId);
|
||||
if(org == null)
|
||||
if (org == null)
|
||||
{
|
||||
throw new BadRequestException("Organization not found");
|
||||
}
|
||||
|
||||
if(!org.UseGroups)
|
||||
if (!org.UseGroups)
|
||||
{
|
||||
throw new BadRequestException("This organization cannot use groups.");
|
||||
}
|
||||
|
||||
if(group.Id == default(Guid))
|
||||
if (group.Id == default(Guid))
|
||||
{
|
||||
group.CreationDate = group.RevisionDate = DateTime.UtcNow;
|
||||
|
||||
if(collections == null)
|
||||
if (collections == null)
|
||||
{
|
||||
await _groupRepository.CreateAsync(group);
|
||||
}
|
||||
@ -72,7 +72,7 @@ namespace Bit.Core.Services
|
||||
public async Task DeleteUserAsync(Group group, Guid organizationUserId)
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByIdAsync(organizationUserId);
|
||||
if(orgUser == null || orgUser.OrganizationId != group.OrganizationId)
|
||||
if (orgUser == null || orgUser.OrganizationId != group.OrganizationId)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
@ -338,10 +338,10 @@ namespace Bit.Core.Services
|
||||
private async Task<string> RenderAsync<T>(string templateName, T model)
|
||||
{
|
||||
await RegisterHelpersAndPartialsAsync();
|
||||
if(!_templateCache.TryGetValue(templateName, out var template))
|
||||
if (!_templateCache.TryGetValue(templateName, out var template))
|
||||
{
|
||||
var source = await ReadSourceAsync(templateName);
|
||||
if(source != null)
|
||||
if (source != null)
|
||||
{
|
||||
template = Handlebars.Compile(source);
|
||||
_templateCache.Add(templateName, template);
|
||||
@ -354,12 +354,12 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var assembly = typeof(HandlebarsMailService).GetTypeInfo().Assembly;
|
||||
var fullTemplateName = $"{Namespace}.{templateName}.hbs";
|
||||
if(!assembly.GetManifestResourceNames().Any(f => f == fullTemplateName))
|
||||
if (!assembly.GetManifestResourceNames().Any(f => f == fullTemplateName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
using(var s = assembly.GetManifestResourceStream(fullTemplateName))
|
||||
using(var sr = new StreamReader(s))
|
||||
using (var s = assembly.GetManifestResourceStream(fullTemplateName))
|
||||
using (var sr = new StreamReader(s))
|
||||
{
|
||||
return await sr.ReadToEndAsync();
|
||||
}
|
||||
@ -367,7 +367,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task RegisterHelpersAndPartialsAsync()
|
||||
{
|
||||
if(_registeredHelpersAndPartials)
|
||||
if (_registeredHelpersAndPartials)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -384,12 +384,12 @@ namespace Bit.Core.Services
|
||||
|
||||
Handlebars.RegisterHelper("date", (writer, context, parameters) =>
|
||||
{
|
||||
if(parameters.Length == 0 || !(parameters[0] is DateTime))
|
||||
if (parameters.Length == 0 || !(parameters[0] is DateTime))
|
||||
{
|
||||
writer.WriteSafeString(string.Empty);
|
||||
return;
|
||||
}
|
||||
if(parameters.Length > 0 && parameters[1] is string)
|
||||
if (parameters.Length > 0 && parameters[1] is string)
|
||||
{
|
||||
writer.WriteSafeString(((DateTime)parameters[0]).ToString(parameters[1].ToString()));
|
||||
}
|
||||
@ -401,7 +401,7 @@ namespace Bit.Core.Services
|
||||
|
||||
Handlebars.RegisterHelper("usd", (writer, context, parameters) =>
|
||||
{
|
||||
if(parameters.Length == 0 || !(parameters[0] is decimal))
|
||||
if (parameters.Length == 0 || !(parameters[0] is decimal))
|
||||
{
|
||||
writer.WriteSafeString(string.Empty);
|
||||
return;
|
||||
@ -411,7 +411,7 @@ namespace Bit.Core.Services
|
||||
|
||||
Handlebars.RegisterHelper("link", (writer, context, parameters) =>
|
||||
{
|
||||
if(parameters.Length == 0)
|
||||
if (parameters.Length == 0)
|
||||
{
|
||||
writer.WriteSafeString(string.Empty);
|
||||
return;
|
||||
@ -420,12 +420,12 @@ namespace Bit.Core.Services
|
||||
var text = parameters[0].ToString();
|
||||
var href = text;
|
||||
var clickTrackingOff = false;
|
||||
if(parameters.Length == 2)
|
||||
if (parameters.Length == 2)
|
||||
{
|
||||
if(parameters[1] is string)
|
||||
if (parameters[1] is string)
|
||||
{
|
||||
var p1 = parameters[1].ToString();
|
||||
if(p1 == "true" || p1 == "false")
|
||||
if (p1 == "true" || p1 == "false")
|
||||
{
|
||||
clickTrackingOff = p1 == "true";
|
||||
}
|
||||
@ -434,26 +434,26 @@ namespace Bit.Core.Services
|
||||
href = p1;
|
||||
}
|
||||
}
|
||||
else if(parameters[1] is bool)
|
||||
else if (parameters[1] is bool)
|
||||
{
|
||||
clickTrackingOff = (bool)parameters[1];
|
||||
}
|
||||
}
|
||||
else if(parameters.Length > 2)
|
||||
else if (parameters.Length > 2)
|
||||
{
|
||||
if(parameters[1] is string)
|
||||
if (parameters[1] is string)
|
||||
{
|
||||
href = parameters[1].ToString();
|
||||
}
|
||||
if(parameters[2] is string)
|
||||
if (parameters[2] is string)
|
||||
{
|
||||
var p2 = parameters[2].ToString();
|
||||
if(p2 == "true" || p2 == "false")
|
||||
if (p2 == "true" || p2 == "false")
|
||||
{
|
||||
clickTrackingOff = p2 == "true";
|
||||
}
|
||||
}
|
||||
else if(parameters[2] is bool)
|
||||
else if (parameters[2] is bool)
|
||||
{
|
||||
clickTrackingOff = (bool)parameters[2];
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ namespace Bit.Core.Services
|
||||
await InitOrganizationAbilitiesAsync();
|
||||
var newAbility = new OrganizationAbility(organization);
|
||||
|
||||
if(_orgAbilities.ContainsKey(organization.Id))
|
||||
if (_orgAbilities.ContainsKey(organization.Id))
|
||||
{
|
||||
_orgAbilities[organization.Id] = newAbility;
|
||||
}
|
||||
@ -44,7 +44,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public virtual Task DeleteOrganizationAbilityAsync(Guid organizationId)
|
||||
{
|
||||
if(_orgAbilities != null && _orgAbilities.ContainsKey(organizationId))
|
||||
if (_orgAbilities != null && _orgAbilities.ContainsKey(organizationId))
|
||||
{
|
||||
_orgAbilities.Remove(organizationId);
|
||||
}
|
||||
@ -55,7 +55,7 @@ namespace Bit.Core.Services
|
||||
private async Task InitOrganizationAbilitiesAsync()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if(_orgAbilities == null || (now - _lastOrgAbilityRefresh) > _orgAbilitiesRefreshInterval)
|
||||
if (_orgAbilities == null || (now - _lastOrgAbilityRefresh) > _orgAbilitiesRefreshInterval)
|
||||
{
|
||||
var abilities = await _organizationRepository.GetManyAbilitiesAsync();
|
||||
_orgAbilities = abilities.ToDictionary(a => a.Id);
|
||||
|
@ -44,12 +44,12 @@ namespace Bit.Core.Services
|
||||
|
||||
var certThumbprint = environment.IsDevelopment() ? "207E64A231E8AA32AAF68A61037C075EBEBD553F" :
|
||||
"B34876439FCDA2846505B2EFBBA6C4A951313EBE";
|
||||
if(_globalSettings.SelfHosted)
|
||||
if (_globalSettings.SelfHosted)
|
||||
{
|
||||
_certificate = CoreHelpers.GetEmbeddedCertificateAsync("licensing.cer", null)
|
||||
.GetAwaiter().GetResult();
|
||||
}
|
||||
else if(CoreHelpers.SettingHasValue(_globalSettings.Storage?.ConnectionString) &&
|
||||
else if (CoreHelpers.SettingHasValue(_globalSettings.Storage?.ConnectionString) &&
|
||||
CoreHelpers.SettingHasValue(_globalSettings.LicenseCertificatePassword))
|
||||
{
|
||||
var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString);
|
||||
@ -62,13 +62,13 @@ namespace Bit.Core.Services
|
||||
_certificate = CoreHelpers.GetCertificate(certThumbprint);
|
||||
}
|
||||
|
||||
if(_certificate == null || !_certificate.Thumbprint.Equals(CoreHelpers.CleanCertificateThumbprint(certThumbprint),
|
||||
if (_certificate == null || !_certificate.Thumbprint.Equals(CoreHelpers.CleanCertificateThumbprint(certThumbprint),
|
||||
StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
throw new Exception("Invalid licensing certificate.");
|
||||
}
|
||||
|
||||
if(_globalSettings.SelfHosted && !CoreHelpers.SettingHasValue(_globalSettings.LicenseDirectory))
|
||||
if (_globalSettings.SelfHosted && !CoreHelpers.SettingHasValue(_globalSettings.LicenseDirectory))
|
||||
{
|
||||
throw new InvalidOperationException("No license directory.");
|
||||
}
|
||||
@ -76,7 +76,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ValidateOrganizationsAsync()
|
||||
{
|
||||
if(!_globalSettings.SelfHosted)
|
||||
if (!_globalSettings.SelfHosted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -85,29 +85,29 @@ namespace Bit.Core.Services
|
||||
_logger.LogInformation(Constants.BypassFiltersEventId, null,
|
||||
"Validating licenses for {0} organizations.", enabledOrgs.Count);
|
||||
|
||||
foreach(var org in enabledOrgs)
|
||||
foreach (var org in enabledOrgs)
|
||||
{
|
||||
var license = ReadOrganizationLicense(org);
|
||||
if(license == null)
|
||||
if (license == null)
|
||||
{
|
||||
await DisableOrganizationAsync(org, null, "No license file.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var totalLicensedOrgs = enabledOrgs.Count(o => o.LicenseKey.Equals(license.LicenseKey));
|
||||
if(totalLicensedOrgs > 1)
|
||||
if (totalLicensedOrgs > 1)
|
||||
{
|
||||
await DisableOrganizationAsync(org, license, "Multiple organizations.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!license.VerifyData(org, _globalSettings))
|
||||
if (!license.VerifyData(org, _globalSettings))
|
||||
{
|
||||
await DisableOrganizationAsync(org, license, "Invalid data.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!license.VerifySignature(_certificate))
|
||||
if (!license.VerifySignature(_certificate))
|
||||
{
|
||||
await DisableOrganizationAsync(org, license, "Invalid signature.");
|
||||
continue;
|
||||
@ -128,7 +128,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ValidateUsersAsync()
|
||||
{
|
||||
if(!_globalSettings.SelfHosted)
|
||||
if (!_globalSettings.SelfHosted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -137,7 +137,7 @@ namespace Bit.Core.Services
|
||||
_logger.LogInformation(Constants.BypassFiltersEventId, null,
|
||||
"Validating premium for {0} users.", premiumUsers.Count);
|
||||
|
||||
foreach(var user in premiumUsers)
|
||||
foreach (var user in premiumUsers)
|
||||
{
|
||||
await ProcessUserValidationAsync(user);
|
||||
}
|
||||
@ -145,22 +145,22 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<bool> ValidateUserPremiumAsync(User user)
|
||||
{
|
||||
if(!_globalSettings.SelfHosted)
|
||||
if (!_globalSettings.SelfHosted)
|
||||
{
|
||||
return user.Premium;
|
||||
}
|
||||
|
||||
if(!user.Premium)
|
||||
if (!user.Premium)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only check once per day
|
||||
var now = DateTime.UtcNow;
|
||||
if(_userCheckCache.ContainsKey(user.Id))
|
||||
if (_userCheckCache.ContainsKey(user.Id))
|
||||
{
|
||||
var lastCheck = _userCheckCache[user.Id];
|
||||
if(lastCheck < now && now - lastCheck < TimeSpan.FromDays(1))
|
||||
if (lastCheck < now && now - lastCheck < TimeSpan.FromDays(1))
|
||||
{
|
||||
return user.Premium;
|
||||
}
|
||||
@ -182,19 +182,19 @@ namespace Bit.Core.Services
|
||||
private async Task<bool> ProcessUserValidationAsync(User user)
|
||||
{
|
||||
var license = ReadUserLicense(user);
|
||||
if(license == null)
|
||||
if (license == null)
|
||||
{
|
||||
await DisablePremiumAsync(user, null, "No license file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!license.VerifyData(user))
|
||||
if (!license.VerifyData(user))
|
||||
{
|
||||
await DisablePremiumAsync(user, license, "Invalid data.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!license.VerifySignature(_certificate))
|
||||
if (!license.VerifySignature(_certificate))
|
||||
{
|
||||
await DisablePremiumAsync(user, license, "Invalid signature.");
|
||||
return false;
|
||||
@ -222,7 +222,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public byte[] SignLicense(ILicense license)
|
||||
{
|
||||
if(_globalSettings.SelfHosted || !_certificate.HasPrivateKey)
|
||||
if (_globalSettings.SelfHosted || !_certificate.HasPrivateKey)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot sign licenses.");
|
||||
}
|
||||
@ -233,7 +233,7 @@ namespace Bit.Core.Services
|
||||
private UserLicense ReadUserLicense(User user)
|
||||
{
|
||||
var filePath = $"{_globalSettings.LicenseDirectory}/user/{user.Id}.json";
|
||||
if(!File.Exists(filePath))
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -245,7 +245,7 @@ namespace Bit.Core.Services
|
||||
private OrganizationLicense ReadOrganizationLicense(Organization organization)
|
||||
{
|
||||
var filePath = $"{_globalSettings.LicenseDirectory}/organization/{organization.Id}.json";
|
||||
if(!File.Exists(filePath))
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace Bit.Core.Services
|
||||
var cipherDirPath = $"{_baseDirPath}/{cipher.Id}";
|
||||
CreateDirectoryIfNotExists(cipherDirPath);
|
||||
|
||||
using(var fs = File.Create($"{cipherDirPath}/{attachmentId}"))
|
||||
using (var fs = File.Create($"{cipherDirPath}/{attachmentId}"))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
await stream.CopyToAsync(fs);
|
||||
@ -36,7 +36,7 @@ namespace Bit.Core.Services
|
||||
var tempCipherOrgDirPath = $"{_baseTempDirPath}/{cipherId}/{organizationId}";
|
||||
CreateDirectoryIfNotExists(tempCipherOrgDirPath);
|
||||
|
||||
using(var fs = File.Create($"{tempCipherOrgDirPath}/{attachmentId}"))
|
||||
using (var fs = File.Create($"{tempCipherOrgDirPath}/{attachmentId}"))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
await stream.CopyToAsync(fs);
|
||||
@ -47,13 +47,13 @@ namespace Bit.Core.Services
|
||||
{
|
||||
await InitAsync();
|
||||
var sourceFilePath = $"{_baseTempDirPath}/{cipherId}/{organizationId}/{attachmentId}";
|
||||
if(!File.Exists(sourceFilePath))
|
||||
if (!File.Exists(sourceFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var destFilePath = $"{_baseDirPath}/{cipherId}/{attachmentId}";
|
||||
if(!File.Exists(destFilePath))
|
||||
if (!File.Exists(destFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace Bit.Core.Services
|
||||
DeleteFileIfExists($"{_baseTempDirPath}/{cipherId}/{organizationId}/{attachmentId}");
|
||||
|
||||
var originalFilePath = $"{_baseTempDirPath}/{cipherId}/{attachmentId}";
|
||||
if(!File.Exists(originalFilePath))
|
||||
if (!File.Exists(originalFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -115,7 +115,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private void DeleteFileIfExists(string path)
|
||||
{
|
||||
if(File.Exists(path))
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
@ -123,7 +123,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private void DeleteDirectoryIfExists(string path)
|
||||
{
|
||||
if(Directory.Exists(path))
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
@ -131,7 +131,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private void CreateDirectoryIfNotExists(string path)
|
||||
{
|
||||
if(!Directory.Exists(path))
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
@ -139,12 +139,12 @@ namespace Bit.Core.Services
|
||||
|
||||
private Task InitAsync()
|
||||
{
|
||||
if(!Directory.Exists(_baseDirPath))
|
||||
if (!Directory.Exists(_baseDirPath))
|
||||
{
|
||||
Directory.CreateDirectory(_baseDirPath);
|
||||
}
|
||||
|
||||
if(!Directory.Exists(_baseTempDirPath))
|
||||
if (!Directory.Exists(_baseTempDirPath))
|
||||
{
|
||||
Directory.CreateDirectory(_baseTempDirPath);
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ namespace Bit.Core.Services
|
||||
GlobalSettings globalSettings,
|
||||
ILogger<MailKitSmtpMailDeliveryService> logger)
|
||||
{
|
||||
if(globalSettings.Mail?.Smtp?.Host == null)
|
||||
if (globalSettings.Mail?.Smtp?.Host == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(globalSettings.Mail.Smtp.Host));
|
||||
}
|
||||
if(globalSettings.Mail?.ReplyToEmail?.Contains("@") ?? false)
|
||||
if (globalSettings.Mail?.ReplyToEmail?.Contains("@") ?? false)
|
||||
{
|
||||
_replyDomain = globalSettings.Mail.ReplyToEmail.Split('@')[1];
|
||||
}
|
||||
@ -35,40 +35,40 @@ namespace Bit.Core.Services
|
||||
var mimeMessage = new MimeMessage();
|
||||
mimeMessage.From.Add(new MailboxAddress(_globalSettings.SiteName, _globalSettings.Mail.ReplyToEmail));
|
||||
mimeMessage.Subject = message.Subject;
|
||||
if(!string.IsNullOrWhiteSpace(_replyDomain))
|
||||
if (!string.IsNullOrWhiteSpace(_replyDomain))
|
||||
{
|
||||
mimeMessage.MessageId = $"<{Guid.NewGuid()}@{_replyDomain}>";
|
||||
}
|
||||
|
||||
foreach(var address in message.ToEmails)
|
||||
foreach (var address in message.ToEmails)
|
||||
{
|
||||
mimeMessage.To.Add(new MailboxAddress(address));
|
||||
}
|
||||
|
||||
if(message.BccEmails != null)
|
||||
if (message.BccEmails != null)
|
||||
{
|
||||
foreach(var address in message.BccEmails)
|
||||
foreach (var address in message.BccEmails)
|
||||
{
|
||||
mimeMessage.Bcc.Add(new MailboxAddress(address));
|
||||
}
|
||||
}
|
||||
|
||||
var builder = new BodyBuilder();
|
||||
if(!string.IsNullOrWhiteSpace(message.TextContent))
|
||||
if (!string.IsNullOrWhiteSpace(message.TextContent))
|
||||
{
|
||||
builder.TextBody = message.TextContent;
|
||||
}
|
||||
builder.HtmlBody = message.HtmlContent;
|
||||
mimeMessage.Body = builder.ToMessageBody();
|
||||
|
||||
using(var client = new SmtpClient())
|
||||
using (var client = new SmtpClient())
|
||||
{
|
||||
if(_globalSettings.Mail.Smtp.TrustServer)
|
||||
if (_globalSettings.Mail.Smtp.TrustServer)
|
||||
{
|
||||
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
||||
}
|
||||
|
||||
if(!_globalSettings.Mail.Smtp.StartTls && !_globalSettings.Mail.Smtp.Ssl &&
|
||||
if (!_globalSettings.Mail.Smtp.StartTls && !_globalSettings.Mail.Smtp.Ssl &&
|
||||
_globalSettings.Mail.Smtp.Port == 25)
|
||||
{
|
||||
await client.ConnectAsync(_globalSettings.Mail.Smtp.Host, _globalSettings.Mail.Smtp.Port,
|
||||
@ -81,7 +81,7 @@ namespace Bit.Core.Services
|
||||
await client.ConnectAsync(_globalSettings.Mail.Smtp.Host, _globalSettings.Mail.Smtp.Port, useSsl);
|
||||
}
|
||||
|
||||
if(CoreHelpers.SettingHasValue(_globalSettings.Mail.Smtp.Username) &&
|
||||
if (CoreHelpers.SettingHasValue(_globalSettings.Mail.Smtp.Username) &&
|
||||
CoreHelpers.SettingHasValue(_globalSettings.Mail.Smtp.Password))
|
||||
{
|
||||
await client.AuthenticateAsync(_globalSettings.Mail.Smtp.Username,
|
||||
|
@ -24,16 +24,16 @@ namespace Bit.Core.Services
|
||||
ILogger<RelayPushNotificationService> relayLogger,
|
||||
ILogger<NotificationsApiPushNotificationService> hubLogger)
|
||||
{
|
||||
if(globalSettings.SelfHosted)
|
||||
if (globalSettings.SelfHosted)
|
||||
{
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.PushRelayBaseUri) &&
|
||||
if (CoreHelpers.SettingHasValue(globalSettings.PushRelayBaseUri) &&
|
||||
globalSettings.Installation?.Id != null &&
|
||||
CoreHelpers.SettingHasValue(globalSettings.Installation?.Key))
|
||||
{
|
||||
_services.Add(new RelayPushNotificationService(deviceRepository, globalSettings,
|
||||
httpContextAccessor, relayLogger));
|
||||
}
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
||||
if (CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
||||
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
||||
{
|
||||
_services.Add(new NotificationsApiPushNotificationService(
|
||||
@ -42,12 +42,12 @@ namespace Bit.Core.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.NotificationHub.ConnectionString))
|
||||
if (CoreHelpers.SettingHasValue(globalSettings.NotificationHub.ConnectionString))
|
||||
{
|
||||
_services.Add(new NotificationHubPushNotificationService(installationDeviceRepository,
|
||||
globalSettings, httpContextAccessor));
|
||||
}
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
||||
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
||||
{
|
||||
_services.Add(new AzureQueuePushNotificationService(globalSettings, httpContextAccessor));
|
||||
}
|
||||
@ -138,9 +138,9 @@ namespace Bit.Core.Services
|
||||
|
||||
private void PushToServices(Func<IPushNotificationService, Task> pushFunc)
|
||||
{
|
||||
if(_services != null)
|
||||
if (_services != null)
|
||||
{
|
||||
foreach(var service in _services)
|
||||
foreach (var service in _services)
|
||||
{
|
||||
pushFunc(service);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
// We cannot send org pushes since access logic is much more complicated than just the fact that they belong
|
||||
// to the organization. Potentially we could blindly send to just users that have the access all permission
|
||||
@ -59,7 +59,7 @@ namespace Bit.Core.Services
|
||||
|
||||
// await SendPayloadToOrganizationAsync(cipher.OrganizationId.Value, type, message, true);
|
||||
}
|
||||
else if(cipher.UserId.HasValue)
|
||||
else if (cipher.UserId.HasValue)
|
||||
{
|
||||
var message = new SyncCipherPushNotification
|
||||
{
|
||||
@ -151,7 +151,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var tag = BuildTag($"template:payload_userId:{userId}", identifier);
|
||||
await SendPayloadAsync(tag, type, payload);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
@ -162,7 +162,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var tag = BuildTag($"template:payload && organizationId:{orgId}", identifier);
|
||||
await SendPayloadAsync(tag, type, payload);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
@ -170,7 +170,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
||||
{
|
||||
if(!excludeCurrentContext)
|
||||
if (!excludeCurrentContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -182,7 +182,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private string BuildTag(string tag, string identifier)
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(identifier))
|
||||
if (!string.IsNullOrWhiteSpace(identifier))
|
||||
{
|
||||
tag += $" && !deviceIdentifier:{identifier}";
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace Bit.Core.Services
|
||||
public async Task CreateOrUpdateRegistrationAsync(string pushToken, string deviceId, string userId,
|
||||
string identifier, DeviceType type)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(pushToken))
|
||||
if (string.IsNullOrWhiteSpace(pushToken))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -47,13 +47,13 @@ namespace Bit.Core.Services
|
||||
$"userId:{userId}"
|
||||
};
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(identifier))
|
||||
if (!string.IsNullOrWhiteSpace(identifier))
|
||||
{
|
||||
installation.Tags.Add("deviceIdentifier:" + identifier);
|
||||
}
|
||||
|
||||
string payloadTemplate = null, messageTemplate = null, badgeMessageTemplate = null;
|
||||
switch(type)
|
||||
switch (type)
|
||||
{
|
||||
case DeviceType.Android:
|
||||
payloadTemplate = "{\"data\":{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}}}";
|
||||
@ -88,7 +88,7 @@ namespace Bit.Core.Services
|
||||
userId, identifier);
|
||||
|
||||
await _client.CreateOrUpdateInstallationAsync(installation);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
@ -97,7 +97,7 @@ namespace Bit.Core.Services
|
||||
private void BuildInstallationTemplate(Installation installation, string templateId, string templateBody,
|
||||
string userId, string identifier)
|
||||
{
|
||||
if(templateBody == null)
|
||||
if (templateBody == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -114,7 +114,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
};
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(identifier))
|
||||
if (!string.IsNullOrWhiteSpace(identifier))
|
||||
{
|
||||
template.Tags.Add($"{fullTemplateId}_deviceIdentifier:{identifier}");
|
||||
}
|
||||
@ -127,14 +127,14 @@ namespace Bit.Core.Services
|
||||
try
|
||||
{
|
||||
await _client.DeleteInstallationAsync(deviceId);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
if (InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.DeleteAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
if(e.InnerException == null || !e.InnerException.Message.Contains("(404) Not Found"))
|
||||
if (e.InnerException == null || !e.InnerException.Message.Contains("(404) Not Found"))
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
@ -144,7 +144,7 @@ namespace Bit.Core.Services
|
||||
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||
{
|
||||
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Add, $"organizationId:{organizationId}");
|
||||
if(deviceIds.Any() && InstallationDeviceEntity.IsInstallationDeviceId(deviceIds.First()))
|
||||
if (deviceIds.Any() && InstallationDeviceEntity.IsInstallationDeviceId(deviceIds.First()))
|
||||
{
|
||||
var entities = deviceIds.Select(e => new InstallationDeviceEntity(e));
|
||||
await _installationDeviceRepository.UpsertManyAsync(entities.ToList());
|
||||
@ -155,7 +155,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Remove,
|
||||
$"organizationId:{organizationId}");
|
||||
if(deviceIds.Any() && InstallationDeviceEntity.IsInstallationDeviceId(deviceIds.First()))
|
||||
if (deviceIds.Any() && InstallationDeviceEntity.IsInstallationDeviceId(deviceIds.First()))
|
||||
{
|
||||
var entities = deviceIds.Select(e => new InstallationDeviceEntity(e));
|
||||
await _installationDeviceRepository.UpsertManyAsync(entities.ToList());
|
||||
@ -165,7 +165,7 @@ namespace Bit.Core.Services
|
||||
private async Task PatchTagsForUserDevicesAsync(IEnumerable<string> deviceIds, UpdateOperationType op,
|
||||
string tag)
|
||||
{
|
||||
if(!deviceIds.Any())
|
||||
if (!deviceIds.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -176,24 +176,24 @@ namespace Bit.Core.Services
|
||||
Path = "/tags"
|
||||
};
|
||||
|
||||
if(op == UpdateOperationType.Add)
|
||||
if (op == UpdateOperationType.Add)
|
||||
{
|
||||
operation.Value = tag;
|
||||
}
|
||||
else if(op == UpdateOperationType.Remove)
|
||||
else if (op == UpdateOperationType.Remove)
|
||||
{
|
||||
operation.Path += $"/{tag}";
|
||||
}
|
||||
|
||||
foreach(var id in deviceIds)
|
||||
foreach (var id in deviceIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _client.PatchInstallationAsync(id, new List<PartialUpdateOperation> { operation });
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
if(e.InnerException == null || !e.InnerException.Message.Contains("(404) Not Found"))
|
||||
if (e.InnerException == null || !e.InnerException.Message.Contains("(404) Not Found"))
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
var message = new SyncCipherPushNotification
|
||||
{
|
||||
@ -66,7 +66,7 @@ namespace Bit.Core.Services
|
||||
|
||||
await SendMessageAsync(type, message, true);
|
||||
}
|
||||
else if(cipher.UserId.HasValue)
|
||||
else if (cipher.UserId.HasValue)
|
||||
{
|
||||
var message = new SyncCipherPushNotification
|
||||
{
|
||||
@ -151,7 +151,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
||||
{
|
||||
if(!excludeCurrentContext)
|
||||
if (!excludeCurrentContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,38 +33,38 @@ namespace Bit.Core.Services
|
||||
Guid? savingUserId)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
||||
if(org == null)
|
||||
if (org == null)
|
||||
{
|
||||
throw new BadRequestException("Organization not found");
|
||||
}
|
||||
|
||||
if(!org.UsePolicies)
|
||||
if (!org.UsePolicies)
|
||||
{
|
||||
throw new BadRequestException("This organization cannot use policies.");
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
if(policy.Id == default(Guid))
|
||||
if (policy.Id == default(Guid))
|
||||
{
|
||||
policy.CreationDate = now;
|
||||
}
|
||||
else if(policy.Enabled)
|
||||
else if (policy.Enabled)
|
||||
{
|
||||
var currentPolicy = await _policyRepository.GetByIdAsync(policy.Id);
|
||||
if(!currentPolicy?.Enabled ?? true)
|
||||
if (!currentPolicy?.Enabled ?? true)
|
||||
{
|
||||
if(currentPolicy.Type == Enums.PolicyType.TwoFactorAuthentication)
|
||||
if (currentPolicy.Type == Enums.PolicyType.TwoFactorAuthentication)
|
||||
{
|
||||
Organization organization = null;
|
||||
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(
|
||||
policy.OrganizationId);
|
||||
foreach(var orgUser in orgUsers.Where(ou =>
|
||||
foreach (var orgUser in orgUsers.Where(ou =>
|
||||
ou.Status != Enums.OrganizationUserStatusType.Invited &&
|
||||
ou.Type != Enums.OrganizationUserType.Owner))
|
||||
{
|
||||
if(orgUser.UserId != savingUserId && !await userService.TwoFactorIsEnabledAsync(orgUser))
|
||||
if (orgUser.UserId != savingUserId && !await userService.TwoFactorIsEnabledAsync(orgUser))
|
||||
{
|
||||
if(organization == null)
|
||||
if (organization == null)
|
||||
{
|
||||
organization = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
||||
{
|
||||
if(cipher.OrganizationId.HasValue)
|
||||
if (cipher.OrganizationId.HasValue)
|
||||
{
|
||||
// We cannot send org pushes since access logic is much more complicated than just the fact that they belong
|
||||
// to the organization. Potentially we could blindly send to just users that have the access all permission
|
||||
@ -62,7 +62,7 @@ namespace Bit.Core.Services
|
||||
|
||||
// await SendPayloadToOrganizationAsync(cipher.OrganizationId.Value, type, message, true);
|
||||
}
|
||||
else if(cipher.UserId.HasValue)
|
||||
else if (cipher.UserId.HasValue)
|
||||
{
|
||||
var message = new SyncCipherPushNotification
|
||||
{
|
||||
@ -169,14 +169,14 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
if(!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
||||
if (!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
||||
{
|
||||
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
||||
if(device != null)
|
||||
if (device != null)
|
||||
{
|
||||
request.DeviceId = device.Id.ToString();
|
||||
}
|
||||
if(addIdentifier)
|
||||
if (addIdentifier)
|
||||
{
|
||||
request.Identifier = currentContext.DeviceIdentifier;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||
{
|
||||
if(!deviceIds.Any())
|
||||
if (!deviceIds.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -58,7 +58,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||
{
|
||||
if(!deviceIds.Any())
|
||||
if (!deviceIds.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -108,7 +108,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public Guid? GetProperUserId(ClaimsPrincipal principal)
|
||||
{
|
||||
if(!Guid.TryParse(GetUserId(principal), out var userIdGuid))
|
||||
if (!Guid.TryParse(GetUserId(principal), out var userIdGuid))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -118,13 +118,13 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<User> GetUserByIdAsync(string userId)
|
||||
{
|
||||
if(_currentContext?.User != null &&
|
||||
if (_currentContext?.User != null &&
|
||||
string.Equals(_currentContext.User.Id.ToString(), userId, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return _currentContext.User;
|
||||
}
|
||||
|
||||
if(!Guid.TryParse(userId, out var userIdGuid))
|
||||
if (!Guid.TryParse(userId, out var userIdGuid))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -135,7 +135,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<User> GetUserByIdAsync(Guid userId)
|
||||
{
|
||||
if(_currentContext?.User != null && _currentContext.User.Id == userId)
|
||||
if (_currentContext?.User != null && _currentContext.User.Id == userId)
|
||||
{
|
||||
return _currentContext.User;
|
||||
}
|
||||
@ -147,7 +147,7 @@ namespace Bit.Core.Services
|
||||
public async Task<User> GetUserByPrincipalAsync(ClaimsPrincipal principal)
|
||||
{
|
||||
var userId = GetProperUserId(principal);
|
||||
if(!userId.HasValue)
|
||||
if (!userId.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -162,7 +162,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SaveUserAsync(User user, bool push = false)
|
||||
{
|
||||
if(user.Id == default(Guid))
|
||||
if (user.Id == default(Guid))
|
||||
{
|
||||
throw new ApplicationException("Use register method to create a new user.");
|
||||
}
|
||||
@ -170,7 +170,7 @@ namespace Bit.Core.Services
|
||||
user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow;
|
||||
await _userRepository.ReplaceAsync(user);
|
||||
|
||||
if(push)
|
||||
if (push)
|
||||
{
|
||||
// push
|
||||
await _pushService.PushSyncSettingsAsync(user.Id);
|
||||
@ -181,18 +181,18 @@ namespace Bit.Core.Services
|
||||
{
|
||||
// Check if user is the only owner of any organizations.
|
||||
var onlyOwnerCount = await _organizationUserRepository.GetCountByOnlyOwnerAsync(user.Id);
|
||||
if(onlyOwnerCount > 0)
|
||||
if (onlyOwnerCount > 0)
|
||||
{
|
||||
var deletedOrg = false;
|
||||
var orgs = await _organizationUserRepository.GetManyDetailsByUserAsync(user.Id,
|
||||
OrganizationUserStatusType.Confirmed);
|
||||
if(orgs.Count == 1)
|
||||
if (orgs.Count == 1)
|
||||
{
|
||||
var org = await _organizationRepository.GetByIdAsync(orgs.First().OrganizationId);
|
||||
if(org != null && (!org.Enabled || string.IsNullOrWhiteSpace(org.GatewaySubscriptionId)))
|
||||
if (org != null && (!org.Enabled || string.IsNullOrWhiteSpace(org.GatewaySubscriptionId)))
|
||||
{
|
||||
var orgCount = await _organizationUserRepository.GetCountByOrganizationIdAsync(org.Id);
|
||||
if(orgCount <= 1)
|
||||
if (orgCount <= 1)
|
||||
{
|
||||
await _organizationRepository.DeleteAsync(org);
|
||||
deletedOrg = true;
|
||||
@ -200,7 +200,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
if(!deletedOrg)
|
||||
if (!deletedOrg)
|
||||
{
|
||||
return IdentityResult.Failed(new IdentityError
|
||||
{
|
||||
@ -209,13 +209,13 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(user.GatewaySubscriptionId))
|
||||
if (!string.IsNullOrWhiteSpace(user.GatewaySubscriptionId))
|
||||
{
|
||||
try
|
||||
{
|
||||
await CancelPremiumAsync(user, null, true);
|
||||
}
|
||||
catch(GatewayException) { }
|
||||
catch (GatewayException) { }
|
||||
}
|
||||
|
||||
await _userRepository.DeleteAsync(user);
|
||||
@ -225,7 +225,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<IdentityResult> DeleteAsync(User user, string token)
|
||||
{
|
||||
if(!(await VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, "DeleteAccount", token)))
|
||||
if (!(await VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, "DeleteAccount", token)))
|
||||
{
|
||||
return IdentityResult.Failed(ErrorDescriber.InvalidToken());
|
||||
}
|
||||
@ -236,7 +236,7 @@ namespace Bit.Core.Services
|
||||
public async Task SendDeleteConfirmationAsync(string email)
|
||||
{
|
||||
var user = await _userRepository.GetByEmailAsync(email);
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
// No user exists.
|
||||
return;
|
||||
@ -250,25 +250,25 @@ namespace Bit.Core.Services
|
||||
string token, Guid? orgUserId)
|
||||
{
|
||||
var tokenValid = false;
|
||||
if(_globalSettings.DisableUserRegistration && !string.IsNullOrWhiteSpace(token) && orgUserId.HasValue)
|
||||
if (_globalSettings.DisableUserRegistration && !string.IsNullOrWhiteSpace(token) && orgUserId.HasValue)
|
||||
{
|
||||
tokenValid = CoreHelpers.UserInviteTokenIsValid(_organizationServiceDataProtector, token,
|
||||
user.Email, orgUserId.Value, _globalSettings);
|
||||
}
|
||||
|
||||
if(_globalSettings.DisableUserRegistration && !tokenValid)
|
||||
if (_globalSettings.DisableUserRegistration && !tokenValid)
|
||||
{
|
||||
throw new BadRequestException("Open registration has been disabled by the system administrator.");
|
||||
}
|
||||
|
||||
if(orgUserId.HasValue)
|
||||
if (orgUserId.HasValue)
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByIdAsync(orgUserId.Value);
|
||||
if(orgUser != null)
|
||||
if (orgUser != null)
|
||||
{
|
||||
var twoFactorPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(orgUser.OrganizationId,
|
||||
PolicyType.TwoFactorAuthentication);
|
||||
if(twoFactorPolicy != null && twoFactorPolicy.Enabled)
|
||||
if (twoFactorPolicy != null && twoFactorPolicy.Enabled)
|
||||
{
|
||||
user.SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
{
|
||||
@ -285,7 +285,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var result = await base.CreateAsync(user, masterPassword);
|
||||
if(result == IdentityResult.Success)
|
||||
if (result == IdentityResult.Success)
|
||||
{
|
||||
await _mailService.SendWelcomeEmailAsync(user);
|
||||
}
|
||||
@ -296,13 +296,13 @@ namespace Bit.Core.Services
|
||||
public async Task SendMasterPasswordHintAsync(string email)
|
||||
{
|
||||
var user = await _userRepository.GetByEmailAsync(email);
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
// No user exists. Do we want to send an email telling them this in the future?
|
||||
return;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(user.MasterPasswordHint))
|
||||
if (string.IsNullOrWhiteSpace(user.MasterPasswordHint))
|
||||
{
|
||||
await _mailService.SendNoMasterPasswordHintEmailAsync(email);
|
||||
return;
|
||||
@ -314,7 +314,7 @@ namespace Bit.Core.Services
|
||||
public async Task SendTwoFactorEmailAsync(User user)
|
||||
{
|
||||
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Email);
|
||||
if(provider == null || provider.MetaData == null || !provider.MetaData.ContainsKey("Email"))
|
||||
if (provider == null || provider.MetaData == null || !provider.MetaData.ContainsKey("Email"))
|
||||
{
|
||||
throw new ArgumentNullException("No email.");
|
||||
}
|
||||
@ -328,7 +328,7 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> VerifyTwoFactorEmailAsync(User user, string token)
|
||||
{
|
||||
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Email);
|
||||
if(provider == null || provider.MetaData == null || !provider.MetaData.ContainsKey("Email"))
|
||||
if (provider == null || provider.MetaData == null || !provider.MetaData.ContainsKey("Email"))
|
||||
{
|
||||
throw new ArgumentNullException("No email.");
|
||||
}
|
||||
@ -361,13 +361,13 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<bool> CompleteU2fRegistrationAsync(User user, int id, string name, string deviceResponse)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(deviceResponse))
|
||||
if (string.IsNullOrWhiteSpace(deviceResponse))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var challenges = await _u2fRepository.GetManyByUserIdAsync(user.Id);
|
||||
if(!challenges?.Any() ?? true)
|
||||
if (!challenges?.Any() ?? true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -384,28 +384,28 @@ namespace Bit.Core.Services
|
||||
|
||||
// Add device
|
||||
var providers = user.GetTwoFactorProviders();
|
||||
if(providers == null)
|
||||
if (providers == null)
|
||||
{
|
||||
providers = new Dictionary<TwoFactorProviderType, TwoFactorProvider>();
|
||||
}
|
||||
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.U2f);
|
||||
if(provider == null)
|
||||
if (provider == null)
|
||||
{
|
||||
provider = new TwoFactorProvider();
|
||||
}
|
||||
if(provider.MetaData == null)
|
||||
if (provider.MetaData == null)
|
||||
{
|
||||
provider.MetaData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
if(provider.MetaData.Count >= 5)
|
||||
if (provider.MetaData.Count >= 5)
|
||||
{
|
||||
// Can only register up to 5 keys
|
||||
return false;
|
||||
}
|
||||
|
||||
var keyId = $"Key{id}";
|
||||
if(provider.MetaData.ContainsKey(keyId))
|
||||
if (provider.MetaData.ContainsKey(keyId))
|
||||
{
|
||||
provider.MetaData.Remove(keyId);
|
||||
}
|
||||
@ -421,7 +421,7 @@ namespace Bit.Core.Services
|
||||
Counter = reg.Counter
|
||||
});
|
||||
|
||||
if(providers.ContainsKey(TwoFactorProviderType.U2f))
|
||||
if (providers.ContainsKey(TwoFactorProviderType.U2f))
|
||||
{
|
||||
providers.Remove(TwoFactorProviderType.U2f);
|
||||
}
|
||||
@ -431,7 +431,7 @@ namespace Bit.Core.Services
|
||||
await UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.U2f);
|
||||
return true;
|
||||
}
|
||||
catch(U2fException e)
|
||||
catch (U2fException e)
|
||||
{
|
||||
Logger.LogError(e, "Complete U2F registration error.");
|
||||
return false;
|
||||
@ -441,19 +441,19 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> DeleteU2fKeyAsync(User user, int id)
|
||||
{
|
||||
var providers = user.GetTwoFactorProviders();
|
||||
if(providers == null)
|
||||
if (providers == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var keyName = $"Key{id}";
|
||||
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.U2f);
|
||||
if(!provider?.MetaData?.ContainsKey(keyName) ?? true)
|
||||
if (!provider?.MetaData?.ContainsKey(keyName) ?? true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(provider.MetaData.Count < 2)
|
||||
if (provider.MetaData.Count < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -467,7 +467,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SendEmailVerificationAsync(User user)
|
||||
{
|
||||
if(user.EmailVerified)
|
||||
if (user.EmailVerified)
|
||||
{
|
||||
throw new BadRequestException("Email already verified.");
|
||||
}
|
||||
@ -479,7 +479,7 @@ namespace Bit.Core.Services
|
||||
public async Task InitiateEmailChangeAsync(User user, string newEmail)
|
||||
{
|
||||
var existingUser = await _userRepository.GetByEmailAsync(newEmail);
|
||||
if(existingUser != null)
|
||||
if (existingUser != null)
|
||||
{
|
||||
await _mailService.SendChangeEmailAlreadyExistsEmailAsync(user.Email, newEmail);
|
||||
return;
|
||||
@ -493,25 +493,25 @@ namespace Bit.Core.Services
|
||||
string newMasterPassword, string token, string key)
|
||||
{
|
||||
var verifyPasswordResult = _passwordHasher.VerifyHashedPassword(user, user.MasterPassword, masterPassword);
|
||||
if(verifyPasswordResult == PasswordVerificationResult.Failed)
|
||||
if (verifyPasswordResult == PasswordVerificationResult.Failed)
|
||||
{
|
||||
return IdentityResult.Failed(_identityErrorDescriber.PasswordMismatch());
|
||||
}
|
||||
|
||||
if(!await base.VerifyUserTokenAsync(user, _identityOptions.Tokens.ChangeEmailTokenProvider,
|
||||
if (!await base.VerifyUserTokenAsync(user, _identityOptions.Tokens.ChangeEmailTokenProvider,
|
||||
GetChangeEmailTokenPurpose(newEmail), token))
|
||||
{
|
||||
return IdentityResult.Failed(_identityErrorDescriber.InvalidToken());
|
||||
}
|
||||
|
||||
var existingUser = await _userRepository.GetByEmailAsync(newEmail);
|
||||
if(existingUser != null && existingUser.Id != user.Id)
|
||||
if (existingUser != null && existingUser.Id != user.Id)
|
||||
{
|
||||
return IdentityResult.Failed(_identityErrorDescriber.DuplicateEmail(newEmail));
|
||||
}
|
||||
|
||||
var result = await UpdatePasswordHash(user, newMasterPassword);
|
||||
if(!result.Succeeded)
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@ -534,15 +534,15 @@ namespace Bit.Core.Services
|
||||
public async Task<IdentityResult> ChangePasswordAsync(User user, string masterPassword, string newMasterPassword,
|
||||
string key)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if(await CheckPasswordAsync(user, masterPassword))
|
||||
if (await CheckPasswordAsync(user, masterPassword))
|
||||
{
|
||||
var result = await UpdatePasswordHash(user, newMasterPassword);
|
||||
if(!result.Succeeded)
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@ -564,15 +564,15 @@ namespace Bit.Core.Services
|
||||
public async Task<IdentityResult> ChangeKdfAsync(User user, string masterPassword, string newMasterPassword,
|
||||
string key, KdfType kdf, int kdfIterations)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if(await CheckPasswordAsync(user, masterPassword))
|
||||
if (await CheckPasswordAsync(user, masterPassword))
|
||||
{
|
||||
var result = await UpdatePasswordHash(user, newMasterPassword);
|
||||
if(!result.Succeeded)
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@ -593,18 +593,18 @@ namespace Bit.Core.Services
|
||||
public async Task<IdentityResult> UpdateKeyAsync(User user, string masterPassword, string key, string privateKey,
|
||||
IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if(await CheckPasswordAsync(user, masterPassword))
|
||||
if (await CheckPasswordAsync(user, masterPassword))
|
||||
{
|
||||
user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow;
|
||||
user.SecurityStamp = Guid.NewGuid().ToString();
|
||||
user.Key = key;
|
||||
user.PrivateKey = privateKey;
|
||||
if(ciphers.Any() || folders.Any())
|
||||
if (ciphers.Any() || folders.Any())
|
||||
{
|
||||
await _cipherRepository.UpdateUserKeysAndCiphersAsync(user, ciphers, folders);
|
||||
}
|
||||
@ -623,15 +623,15 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<IdentityResult> RefreshSecurityStampAsync(User user, string masterPassword)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if(await CheckPasswordAsync(user, masterPassword))
|
||||
if (await CheckPasswordAsync(user, masterPassword))
|
||||
{
|
||||
var result = await base.UpdateSecurityStampAsync(user);
|
||||
if(!result.Succeeded)
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@ -656,7 +656,7 @@ namespace Bit.Core.Services
|
||||
IOrganizationService organizationService)
|
||||
{
|
||||
var providers = user.GetTwoFactorProviders();
|
||||
if(!providers?.ContainsKey(type) ?? true)
|
||||
if (!providers?.ContainsKey(type) ?? true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -666,7 +666,7 @@ namespace Bit.Core.Services
|
||||
await SaveUserAsync(user);
|
||||
await _eventService.LogUserEventAsync(user.Id, EventType.User_Disabled2fa);
|
||||
|
||||
if(!await TwoFactorIsEnabledAsync(user))
|
||||
if (!await TwoFactorIsEnabledAsync(user))
|
||||
{
|
||||
await CheckPoliciesOnTwoFactorRemovalAsync(user, organizationService);
|
||||
}
|
||||
@ -676,18 +676,18 @@ namespace Bit.Core.Services
|
||||
IOrganizationService organizationService)
|
||||
{
|
||||
var user = await _userRepository.GetByEmailAsync(email);
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
// No user exists. Do we want to send an email telling them this in the future?
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!await CheckPasswordAsync(user, masterPassword))
|
||||
if (!await CheckPasswordAsync(user, masterPassword))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(string.Compare(user.TwoFactorRecoveryCode, recoveryCode, true) != 0)
|
||||
if (string.Compare(user.TwoFactorRecoveryCode, recoveryCode, true) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -705,17 +705,17 @@ namespace Bit.Core.Services
|
||||
public async Task<Tuple<bool, string>> SignUpPremiumAsync(User user, string paymentToken,
|
||||
PaymentMethodType paymentMethodType, short additionalStorageGb, UserLicense license)
|
||||
{
|
||||
if(user.Premium)
|
||||
if (user.Premium)
|
||||
{
|
||||
throw new BadRequestException("Already a premium user.");
|
||||
}
|
||||
|
||||
if(additionalStorageGb < 0)
|
||||
if (additionalStorageGb < 0)
|
||||
{
|
||||
throw new BadRequestException("You can't subtract storage!");
|
||||
}
|
||||
|
||||
if((paymentMethodType == PaymentMethodType.GoogleInApp ||
|
||||
if ((paymentMethodType == PaymentMethodType.GoogleInApp ||
|
||||
paymentMethodType == PaymentMethodType.AppleInApp) && additionalStorageGb > 0)
|
||||
{
|
||||
throw new BadRequestException("You cannot add storage with this payment method.");
|
||||
@ -723,14 +723,14 @@ namespace Bit.Core.Services
|
||||
|
||||
string paymentIntentClientSecret = null;
|
||||
IPaymentService paymentService = null;
|
||||
if(_globalSettings.SelfHosted)
|
||||
if (_globalSettings.SelfHosted)
|
||||
{
|
||||
if(license == null || !_licenseService.VerifyLicense(license))
|
||||
if (license == null || !_licenseService.VerifyLicense(license))
|
||||
{
|
||||
throw new BadRequestException("Invalid license.");
|
||||
}
|
||||
|
||||
if(!license.CanUse(user))
|
||||
if (!license.CanUse(user))
|
||||
{
|
||||
throw new BadRequestException("This license is not valid for this user.");
|
||||
}
|
||||
@ -748,7 +748,7 @@ namespace Bit.Core.Services
|
||||
user.Premium = true;
|
||||
user.RevisionDate = DateTime.UtcNow;
|
||||
|
||||
if(_globalSettings.SelfHosted)
|
||||
if (_globalSettings.SelfHosted)
|
||||
{
|
||||
user.MaxStorageGb = 10240; // 10 TB
|
||||
user.LicenseKey = license.LicenseKey;
|
||||
@ -776,21 +776,21 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task IapCheckAsync(User user, PaymentMethodType paymentMethodType)
|
||||
{
|
||||
if(paymentMethodType != PaymentMethodType.AppleInApp)
|
||||
if (paymentMethodType != PaymentMethodType.AppleInApp)
|
||||
{
|
||||
throw new BadRequestException("Payment method not supported for in-app purchases.");
|
||||
}
|
||||
|
||||
if(user.Premium)
|
||||
if (user.Premium)
|
||||
{
|
||||
throw new BadRequestException("Already a premium user.");
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(user.GatewayCustomerId))
|
||||
if (!string.IsNullOrWhiteSpace(user.GatewayCustomerId))
|
||||
{
|
||||
var customerService = new Stripe.CustomerService();
|
||||
var customer = await customerService.GetAsync(user.GatewayCustomerId);
|
||||
if(customer != null && customer.Balance != 0)
|
||||
if (customer != null && customer.Balance != 0)
|
||||
{
|
||||
throw new BadRequestException("Customer balance cannot exist when using in-app purchases.");
|
||||
}
|
||||
@ -799,17 +799,17 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task UpdateLicenseAsync(User user, UserLicense license)
|
||||
{
|
||||
if(!_globalSettings.SelfHosted)
|
||||
if (!_globalSettings.SelfHosted)
|
||||
{
|
||||
throw new InvalidOperationException("Licenses require self hosting.");
|
||||
}
|
||||
|
||||
if(license == null || !_licenseService.VerifyLicense(license))
|
||||
if (license == null || !_licenseService.VerifyLicense(license))
|
||||
{
|
||||
throw new BadRequestException("Invalid license.");
|
||||
}
|
||||
|
||||
if(!license.CanUse(user))
|
||||
if (!license.CanUse(user))
|
||||
{
|
||||
throw new BadRequestException("This license is not valid for this user.");
|
||||
}
|
||||
@ -828,12 +828,12 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<string> AdjustStorageAsync(User user, short storageAdjustmentGb)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if(!user.Premium)
|
||||
if (!user.Premium)
|
||||
{
|
||||
throw new BadRequestException("Not a premium user.");
|
||||
}
|
||||
@ -846,13 +846,13 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ReplacePaymentMethodAsync(User user, string paymentToken, PaymentMethodType paymentMethodType)
|
||||
{
|
||||
if(paymentToken.StartsWith("btok_"))
|
||||
if (paymentToken.StartsWith("btok_"))
|
||||
{
|
||||
throw new BadRequestException("Invalid token.");
|
||||
}
|
||||
|
||||
var updated = await _paymentService.UpdatePaymentMethodAsync(user, paymentMethodType, paymentToken);
|
||||
if(updated)
|
||||
if (updated)
|
||||
{
|
||||
await SaveUserAsync(user);
|
||||
}
|
||||
@ -861,7 +861,7 @@ namespace Bit.Core.Services
|
||||
public async Task CancelPremiumAsync(User user, bool? endOfPeriod = null, bool accountDelete = false)
|
||||
{
|
||||
var eop = endOfPeriod.GetValueOrDefault(true);
|
||||
if(!endOfPeriod.HasValue && user.PremiumExpirationDate.HasValue &&
|
||||
if (!endOfPeriod.HasValue && user.PremiumExpirationDate.HasValue &&
|
||||
user.PremiumExpirationDate.Value < DateTime.UtcNow)
|
||||
{
|
||||
eop = false;
|
||||
@ -882,7 +882,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task EnablePremiumAsync(User user, DateTime? expirationDate)
|
||||
{
|
||||
if(user != null && !user.Premium && user.Gateway.HasValue)
|
||||
if (user != null && !user.Premium && user.Gateway.HasValue)
|
||||
{
|
||||
user.Premium = true;
|
||||
user.PremiumExpirationDate = expirationDate;
|
||||
@ -899,7 +899,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task DisablePremiumAsync(User user, DateTime? expirationDate)
|
||||
{
|
||||
if(user != null && user.Premium)
|
||||
if (user != null && user.Premium)
|
||||
{
|
||||
user.Premium = false;
|
||||
user.PremiumExpirationDate = expirationDate;
|
||||
@ -911,7 +911,7 @@ namespace Bit.Core.Services
|
||||
public async Task UpdatePremiumExpirationAsync(Guid userId, DateTime? expirationDate)
|
||||
{
|
||||
var user = await _userRepository.GetByIdAsync(userId);
|
||||
if(user != null)
|
||||
if (user != null)
|
||||
{
|
||||
user.PremiumExpirationDate = expirationDate;
|
||||
user.RevisionDate = DateTime.UtcNow;
|
||||
@ -921,12 +921,12 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<UserLicense> GenerateLicenseAsync(User user, SubscriptionInfo subscriptionInfo = null)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if(subscriptionInfo == null && user.Gateway != null)
|
||||
if (subscriptionInfo == null && user.Gateway != null)
|
||||
{
|
||||
subscriptionInfo = await _paymentService.GetSubscriptionAsync(user);
|
||||
}
|
||||
@ -937,13 +937,13 @@ namespace Bit.Core.Services
|
||||
|
||||
public override async Task<bool> CheckPasswordAsync(User user, string password)
|
||||
{
|
||||
if(user == null)
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = await base.VerifyPasswordAsync(Store as IUserPasswordStore<User>, user, password);
|
||||
if(result == PasswordVerificationResult.SuccessRehashNeeded)
|
||||
if (result == PasswordVerificationResult.SuccessRehashNeeded)
|
||||
{
|
||||
await UpdatePasswordHash(user, password, false, false);
|
||||
user.RevisionDate = DateTime.UtcNow;
|
||||
@ -951,7 +951,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var success = result != PasswordVerificationResult.Failed;
|
||||
if(!success)
|
||||
if (!success)
|
||||
{
|
||||
Logger.LogWarning(0, "Invalid password for user {userId}.", user.Id);
|
||||
}
|
||||
@ -961,16 +961,16 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> CanAccessPremium(ITwoFactorProvidersUser user)
|
||||
{
|
||||
var userId = user.GetUserId();
|
||||
if(!userId.HasValue)
|
||||
if (!userId.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(user.GetPremium())
|
||||
if (user.GetPremium())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var orgs = await _currentContext.OrganizationMembershipAsync(_organizationUserRepository, userId.Value);
|
||||
if(!orgs.Any())
|
||||
if (!orgs.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -982,20 +982,20 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> TwoFactorIsEnabledAsync(ITwoFactorProvidersUser user)
|
||||
{
|
||||
var providers = user.GetTwoFactorProviders();
|
||||
if(providers == null)
|
||||
if (providers == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach(var p in providers)
|
||||
foreach (var p in providers)
|
||||
{
|
||||
if(p.Value?.Enabled ?? false)
|
||||
if (p.Value?.Enabled ?? false)
|
||||
{
|
||||
if(!TwoFactorProvider.RequiresPremium(p.Key))
|
||||
if (!TwoFactorProvider.RequiresPremium(p.Key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(await CanAccessPremium(user))
|
||||
if (await CanAccessPremium(user))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -1007,12 +1007,12 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> TwoFactorProviderIsEnabledAsync(TwoFactorProviderType provider, ITwoFactorProvidersUser user)
|
||||
{
|
||||
var providers = user.GetTwoFactorProviders();
|
||||
if(providers == null || !providers.ContainsKey(provider) || !providers[provider].Enabled)
|
||||
if (providers == null || !providers.ContainsKey(provider) || !providers[provider].Enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!TwoFactorProvider.RequiresPremium(provider))
|
||||
if (!TwoFactorProvider.RequiresPremium(provider))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -1023,17 +1023,17 @@ namespace Bit.Core.Services
|
||||
private async Task<IdentityResult> UpdatePasswordHash(User user, string newPassword,
|
||||
bool validatePassword = true, bool refreshStamp = true)
|
||||
{
|
||||
if(validatePassword)
|
||||
if (validatePassword)
|
||||
{
|
||||
var validate = await ValidatePasswordInternal(user, newPassword);
|
||||
if(!validate.Succeeded)
|
||||
if (!validate.Succeeded)
|
||||
{
|
||||
return validate;
|
||||
}
|
||||
}
|
||||
|
||||
user.MasterPassword = _passwordHasher.HashPassword(user, newPassword);
|
||||
if(refreshStamp)
|
||||
if (refreshStamp)
|
||||
{
|
||||
user.SecurityStamp = Guid.NewGuid().ToString();
|
||||
}
|
||||
@ -1044,16 +1044,16 @@ namespace Bit.Core.Services
|
||||
private async Task<IdentityResult> ValidatePasswordInternal(User user, string password)
|
||||
{
|
||||
var errors = new List<IdentityError>();
|
||||
foreach(var v in _passwordValidators)
|
||||
foreach (var v in _passwordValidators)
|
||||
{
|
||||
var result = await v.ValidateAsync(this, user, password);
|
||||
if(!result.Succeeded)
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
errors.AddRange(result.Errors);
|
||||
}
|
||||
}
|
||||
|
||||
if(errors.Count > 0)
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
Logger.LogWarning("User {userId} password validation failed: {errors}.", await GetUserIdAsync(user),
|
||||
string.Join(";", errors.Select(e => e.Code)));
|
||||
@ -1066,7 +1066,7 @@ namespace Bit.Core.Services
|
||||
public void SetTwoFactorProvider(User user, TwoFactorProviderType type)
|
||||
{
|
||||
var providers = user.GetTwoFactorProviders();
|
||||
if(!providers?.ContainsKey(type) ?? true)
|
||||
if (!providers?.ContainsKey(type) ?? true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1074,7 +1074,7 @@ namespace Bit.Core.Services
|
||||
providers[type].Enabled = true;
|
||||
user.SetTwoFactorProviders(providers);
|
||||
|
||||
if(string.IsNullOrWhiteSpace(user.TwoFactorRecoveryCode))
|
||||
if (string.IsNullOrWhiteSpace(user.TwoFactorRecoveryCode))
|
||||
{
|
||||
user.TwoFactorRecoveryCode = CoreHelpers.SecureRandomString(32, upper: false, special: false);
|
||||
}
|
||||
@ -1084,14 +1084,14 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var policies = await _policyRepository.GetManyByUserIdAsync(user.Id);
|
||||
var twoFactorPolicies = policies.Where(p => p.Type == PolicyType.TwoFactorAuthentication && p.Enabled);
|
||||
if(twoFactorPolicies.Any())
|
||||
if (twoFactorPolicies.Any())
|
||||
{
|
||||
var userOrgs = await _organizationUserRepository.GetManyByUserAsync(user.Id);
|
||||
var ownerOrgs = userOrgs.Where(o => o.Type == OrganizationUserType.Owner)
|
||||
.Select(o => o.OrganizationId).ToHashSet();
|
||||
foreach(var policy in twoFactorPolicies)
|
||||
foreach (var policy in twoFactorPolicies)
|
||||
{
|
||||
if(!ownerOrgs.Contains(policy.OrganizationId))
|
||||
if (!ownerOrgs.Contains(policy.OrganizationId))
|
||||
{
|
||||
await organizationService.DeleteUserAsync(policy.OrganizationId, user.Id);
|
||||
var organization = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
||||
|
Reference in New Issue
Block a user