Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ public List<IAtomicAction> GetActions()
return new List<IAtomicAction>(Actions);
}

internal List<AtomicCondition> Conditions { get; set; }
public List<AtomicCondition> Conditions { get; set; }

internal List<AtomicAction> Actions { get; set; }
public List<AtomicAction> Actions { get; set; }

internal void AddAction(AtomicAction atomicAction)
public void AddAction(AtomicAction atomicAction)
{
atomicAction.SynchronizationRule = this;

Expand Down
7 changes: 4 additions & 3 deletions src/ByteSync.Client/Services/Sessions/DataPartIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ public void BuildMap(List<Inventory> inventories)

DataPartsByNames.Clear();

bool isInventoryWithMultipleParts = inventories.Any(i => i.InventoryParts.Count > 1);

var cptInventory = 0;
foreach (var inventory in Inventories)
{
var inventoryLetter = ((char)('A' + cptInventory)).ToString();

if (inventory.InventoryParts.Count == 1)
if (!isInventoryWithMultipleParts)
{
var dataPart = new DataPart(inventoryLetter, inventory);
DataPartsByNames.Add(dataPart.Name, dataPart);
}

if (inventory.InventoryParts.Count > 1)
else
{
var cptPart = 1;
foreach (var inventoryPart in inventory.InventoryParts)
Expand Down
140 changes: 87 additions & 53 deletions src/ByteSync.Client/Services/Updates/UpdateExistingFilesBackuper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,76 +21,110 @@ public UpdateExistingFilesBackuper(IUpdateRepository updateRepository, ILogger<U

public List<Tuple<string, string>> BackedUpFileSystemInfos { get; }

public async Task BackupExistingFilesAsync(CancellationToken cancellationToken)
public Task BackupExistingFilesAsync(CancellationToken cancellationToken)
{
await Task.Run(() => BackupExistingFiles(cancellationToken));
}

private void BackupExistingFiles(CancellationToken cancellationToken)
{
DirectoryInfo applicationBaseDirectoryInfo = new DirectoryInfo(_updateRepository.UpdateData.ApplicationBaseDirectory);

foreach (var fileSystemInfo in applicationBaseDirectoryInfo.GetFileSystemInfos())
return Task.Run(() =>
{
if (cancellationToken.IsCancellationRequested)
try
{
_logger.LogWarning("UpdateExistingFilesBackuper.BackupExistingFiles: Cancellation requested");
var applicationBaseDirectoryInfo = new DirectoryInfo(_updateRepository.UpdateData.ApplicationBaseDirectory);
var filesToBackup = GetFilesToBackup(applicationBaseDirectoryInfo, cancellationToken);

return;
}

if (fileSystemInfo is DirectoryInfo)
{
if (!fileSystemInfo.Name.Equals("Contents", StringComparison.InvariantCultureIgnoreCase) &&
!fileSystemInfo.Name.Equals("ByteSync.app", StringComparison.InvariantCultureIgnoreCase))
foreach (var fileSystemInfo in filesToBackup)
{
_logger.LogInformation("UpdateExistingFilesBackuper.BackupExistingFiles: ignored directory {directory}", fileSystemInfo.FullName);
if (cancellationToken.IsCancellationRequested)
{
_logger.LogWarning("UpdateExistingFilesBackuper.BackupExistingFiles: Cancellation requested");
return;
}

continue;
BackupFileSystemInfo(fileSystemInfo);
}
}

if (fileSystemInfo is FileInfo fi)
catch (OperationCanceledException)
{
// Si l'une des conditions est réunies
// - Le Nom ne contient pas ByteSync
// - Son extension est dans .log, .dat, .xml, .json ou .zip
// - Il commence par unins et finit par .exe
// => On l'ignore
if (!fileSystemInfo.Name.Contains("ByteSync", StringComparison.InvariantCultureIgnoreCase) ||
fi.Extension.ToLower().In(".log", ".dat", ".xml", ".json", ".zip") ||
(fi.Name.StartsWith("unins", StringComparison.InvariantCultureIgnoreCase)
&& fi.Extension.Equals(".exe", StringComparison.InvariantCultureIgnoreCase)))
{
_logger.LogInformation("UpdateExistingFilesBackuper.BackupExistingFiles: ignored file {file}", fileSystemInfo.FullName);

continue;
}
_logger.LogWarning("UpdateExistingFilesBackuper.BackupExistingFiles: Operation was canceled");
}

string previousFullName = fileSystemInfo.FullName;

int cpt = 0;
var backupDestination = $"{fileSystemInfo.FullName}.{UpdateConstants.BAK_EXTENSION}{cpt}";

while (File.Exists(backupDestination) || Directory.Exists(backupDestination))
catch (Exception ex)
{
cpt += 1;
backupDestination = $"{fileSystemInfo.FullName}.{UpdateConstants.BAK_EXTENSION}{cpt}";
_logger.LogError(ex, "UpdateExistingFilesBackuper.BackupExistingFiles: An error occurred");
throw;
}
_logger.LogInformation("UpdateExistingFilesBackuper: Renaming {Source} to {Destination}", previousFullName, backupDestination);
}, cancellationToken);
}

if (fileSystemInfo is FileInfo fileInfo)
private IEnumerable<FileSystemInfo> GetFilesToBackup(DirectoryInfo baseDirectory, CancellationToken cancellationToken)
{
var result = new List<FileSystemInfo>();

foreach (var fileSystemInfo in baseDirectory.GetFileSystemInfos())
{
if (cancellationToken.IsCancellationRequested)
break;

if (fileSystemInfo is DirectoryInfo directoryInfo)
{
fileInfo.MoveTo(backupDestination);
// Only include files specifically named “Contents” or “ByteSync.app”
if (directoryInfo.Name.Equals("Contents", StringComparison.InvariantCultureIgnoreCase) ||
directoryInfo.Name.Equals("ByteSync.app", StringComparison.InvariantCultureIgnoreCase))
{
result.Add(fileSystemInfo);
}
else
{
_logger.LogInformation("UpdateExistingFilesBackuper.GetFilesToBackup: ignored directory {directory}", fileSystemInfo.FullName);
}
}
else if (fileSystemInfo is DirectoryInfo directoryInfo)
else if (fileSystemInfo is FileInfo fileInfo)
{
directoryInfo.MoveTo(backupDestination);
// Only include files that:
// - Contain “ByteSync” in their name
// - Do not have a .log, .dat, .xml, .json or .zip extension
// - Do not start with “unins” if the extension is .exe
bool containsByteSyncName = fileInfo.Name.Contains("ByteSync", StringComparison.InvariantCultureIgnoreCase);
bool hasAllowedExtension = !fileInfo.Extension.ToLower().In(".log", ".dat", ".xml", ".json", ".zip");
bool isUninstaller = fileInfo.Name.StartsWith("unins", StringComparison.InvariantCultureIgnoreCase)
&& fileInfo.Extension.Equals(".exe", StringComparison.InvariantCultureIgnoreCase);

if (containsByteSyncName && hasAllowedExtension && !isUninstaller)
{
result.Add(fileSystemInfo);
}
else
{
_logger.LogInformation("UpdateExistingFilesBackuper.GetFilesToBackup: ignored file {file}", fileSystemInfo.FullName);
}
}
}

return result;
}

private void BackupFileSystemInfo(FileSystemInfo fileSystemInfo)
{
string previousFullName = fileSystemInfo.FullName;

int cpt = 0;
var backupDestination = $"{fileSystemInfo.FullName}.{UpdateConstants.BAK_EXTENSION}{cpt}";

while (File.Exists(backupDestination) || Directory.Exists(backupDestination))
{
cpt += 1;
backupDestination = $"{fileSystemInfo.FullName}.{UpdateConstants.BAK_EXTENSION}{cpt}";
}

_logger.LogInformation("UpdateExistingFilesBackuper: Renaming {Source} to {Destination}", previousFullName, backupDestination);

BackedUpFileSystemInfos.Add(new Tuple<string, string>(previousFullName, backupDestination));
if (fileSystemInfo is FileInfo fileInfo)
{
fileInfo.MoveTo(backupDestination);
}
else if (fileSystemInfo is DirectoryInfo directoryInfo)
{
directoryInfo.MoveTo(backupDestination);
}

BackedUpFileSystemInfos.Add(new Tuple<string, string>(previousFullName, backupDestination));
}
}
}

37 changes: 31 additions & 6 deletions src/ByteSync.Functions/Helpers/Middlewares/JwtMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,21 @@ public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next
if (token != null)
{
var tokenHandler = new JwtSecurityTokenHandler();

try
{
var claims = ValidateToken(tokenHandler, token);

var client = await GetClient(claims);
context.Items.Add(AuthConstants.FUNCTION_CONTEXT_CLIENT, client!);

await BeginScopeAndGoNext(context, next, client);
}
catch (SecurityTokenExpiredException ex)
{
_logger.LogWarning(ex, "Token expired");
await HandleTokenError(context, "Invalid token");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error validating token");
Expand Down Expand Up @@ -97,13 +102,33 @@ private async Task BeginScopeAndGoNext(FunctionContext context, FunctionExecutio
}
}

private static async Task<string?> ExtractToken(FunctionContext context)
private async Task<string?> ExtractToken(FunctionContext context)
{
var requestData = await context.GetHttpRequestDataAsync();
var authorizationHeader = requestData?.Headers.FirstOrDefault(p => p.Key.Equals("Authorization"));
var token = authorizationHeader?.Value.LastOrDefault();
if (requestData == null)
{
return null;
}

// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (!requestData.Headers.TryGetValues("Authorization", out var authorizationValues) || authorizationValues == null)
{
return null;
}

var token = authorizationValues.LastOrDefault();
if (string.IsNullOrWhiteSpace(token))
{
return null;
}

return token;
const string bearerPrefix = "Bearer ";
if (token.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase))
{
token = token.Substring(bearerPrefix.Length);
}

return string.IsNullOrWhiteSpace(token) ? null : token;
}

private TokenValidationParameters BuildTokenValidationParameters()
Expand Down
Loading