diff --git a/src/Application/Entries/Commands/CreateEntry.cs b/src/Application/Entries/Commands/CreateEntry.cs index 3f485f18..430fb41a 100644 --- a/src/Application/Entries/Commands/CreateEntry.cs +++ b/src/Application/Entries/Commands/CreateEntry.cs @@ -82,8 +82,8 @@ public async Task Handle(Command request, CancellationToken cancellati { var baseDirectoryExists = await _context.Entries.AnyAsync( x => request.Path.Trim().ToLower() - .Equals((x.Path.Equals("/") ? (x.Path + x.Name) : (x.Path + "/" + x.Name)).ToLower()) - && x.FileId == null, cancellationToken); + .Equals((x.Path.Equals("/") ? (x.Path + x.Name) : (x.Path + "/" + x.Name)).ToLower()) + && x.FileId == null && x.OwnerId == request.CurrentUser.Id, cancellationToken); if (!request.Path.Equals("/") && !baseDirectoryExists) { @@ -107,9 +107,10 @@ public async Task Handle(Command request, CancellationToken cancellati if (request.IsDirectory) { var entry = await _context.Entries.FirstOrDefaultAsync( - x => x.Name.Trim().Equals(request.Name.Trim()) - && x.Path.Trim().Equals(request.Path.Trim()) - && x.FileId == null, cancellationToken); + x => x.Name.Trim().Equals(request.Name.Trim()) + && x.Path.Trim().Equals(request.Path.Trim()) + && x.FileId == null + && x.OwnerId == request.CurrentUser.Id, cancellationToken); if (entry is not null) { @@ -118,12 +119,43 @@ public async Task Handle(Command request, CancellationToken cancellati } else { - // Make this dynamic + var entries = _context.Entries.AsQueryable() + .Where(x => x.Name.Trim().Substring(0, request.Name.Trim().Length).Equals(request.Name.Trim()) + && x.Path.Trim().Equals(request.Path.Trim()) + && x.FileId != null + && x.OwnerId == request.CurrentUser.Id); + if (request.FileData!.Length > FileUtil.ToByteFromMb(20)) { throw new ConflictException("File size must be lower than 20MB"); } + + if (entries.Any()) + { + var i = 0; + while (true) + { + var temp = ""; + if (i == 0) + { + temp = entryEntity.Name; + } + else + { + temp = $"{entryEntity.Name} ({i})"; + } + var checkEntry = await entries.AnyAsync(x => x.Name.Equals(temp),cancellationToken); + if (!checkEntry) + { + entryEntity.Name = temp; + break; + } + + i++; + } + } + var fileEntity = new FileEntity() { FileData = request.FileData.ToArray(), diff --git a/src/Application/Entries/Commands/MoveEntryToBin.cs b/src/Application/Entries/Commands/MoveEntryToBin.cs index e83c245b..1361eae9 100644 --- a/src/Application/Entries/Commands/MoveEntryToBin.cs +++ b/src/Application/Entries/Commands/MoveEntryToBin.cs @@ -46,15 +46,6 @@ public async Task Handle(Command request, CancellationToken cancellati throw new KeyNotFoundException("Entry does not exist."); } - var entryPath = entry.Path; - var firstSlashIndex = entryPath.IndexOf("/", StringComparison.Ordinal); - var binCheck = entryPath.Substring(0, firstSlashIndex); - - if (binCheck.Contains(BinString)) - { - throw new ConflictException("Entry is already in bin."); - } - if (!entry.Owner.Id.Equals(request.CurrentUser.Id)) { throw new UnauthorizedAccessException("You do not have permission to move this entry into bin."); @@ -80,10 +71,10 @@ public async Task Handle(Command request, CancellationToken cancellati foreach (var childEntry in childEntries) { var childBinPath = ownerUsername + BinString; - if (!entry.Path.Equals("/")) + if (!childEntry.Path.Equals("/")) { - childBinPath += childEntry.Path[c..]; - } // /x /x abc /x/abc de => _bin + /x abc _bin/x/abc de + childBinPath += $"/{childEntry.Path[c..]}"; + } childEntry.OldPath = childEntry.Path; childEntry.Path = childBinPath; childEntry.LastModified = localDateTimeNow; diff --git a/src/Application/Entries/Commands/RestoreBinEntry.cs b/src/Application/Entries/Commands/RestoreBinEntry.cs index da924ade..4daf9698 100644 --- a/src/Application/Entries/Commands/RestoreBinEntry.cs +++ b/src/Application/Entries/Commands/RestoreBinEntry.cs @@ -37,16 +37,16 @@ public Handler(IApplicationDbContext context, IMapper mapper, IDateTimeProvider public async Task Handle(Command request, CancellationToken cancellationToken) { - var entry = await _context.Entries + var binEntry = await _context.Entries .Include(x => x.Owner) .FirstOrDefaultAsync(x => x.Id == request.EntryId, cancellationToken); - if (entry is null) + if (binEntry is null) { throw new KeyNotFoundException("Entry does not exist."); } - var entryPath = entry.Path; + var entryPath = binEntry.Path; var firstSlashIndex = entryPath.IndexOf("/", StringComparison.Ordinal); var binCheck = firstSlashIndex < 0 ? entryPath : entryPath.Substring(0, firstSlashIndex); @@ -56,7 +56,7 @@ public async Task Handle(Command request, CancellationToken cancellati throw new NotChangedException("Entry is not in bin."); } - if (entry.Owner.Id != request.CurrentUser.Id) + if (binEntry.Owner.Id != request.CurrentUser.Id) { throw new UnauthorizedAccessException("You do not have the permission to restore this entry."); } @@ -66,20 +66,16 @@ public async Task Handle(Command request, CancellationToken cancellati var entryCheckPath = entryPath.Replace(binCheck, ""); var entryCheck = await _context.Entries.FirstOrDefaultAsync(x => - (x.Path.Equals("/") ? x.Path + x.Name : x.Path + "/" + x.Name).Equals(entryCheckPath.Equals("/") ? - entryCheckPath + entry.Name : entryCheckPath + "/" + entry.Name), cancellationToken); + (x.Path.Equals("/") ? x.Path + x.Name : x.Path + "/" + x.Name).Equals(entryCheckPath + "/" + binEntry.Name) + && x.OwnerId == request.CurrentUser.Id + && ((x.FileId != null && binEntry.FileId != null) || (x.FileId == null && binEntry.FileId == null)), cancellationToken); if (entryCheck is not null) { - entryCheck.LastModified = localDateTimeNow; - entryCheck.LastModifiedBy = request.CurrentUser.Id; - var dupeResult = _context.Entries.Update(entryCheck); - _context.Entries.Remove(entry); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(dupeResult.Entity); + throw new ConflictException("Entry already exists outside of bin."); } - var splitPath = entry.OldPath!.Split("/"); + var splitPath = binEntry.OldPath!.Split("/"); var currentPath = "/"; foreach (var node in splitPath) { @@ -116,9 +112,9 @@ public async Task Handle(Command request, CancellationToken cancellati currentPath = currentPath.Equals("/") ? currentPath + node : currentPath + "/" + node; } - if (entry.IsDirectory) + if (binEntry.IsDirectory) { - var path = entry.Path[^1].Equals('/') ? entry.Path + entry.Name : $"{entry.Path}/{entry.Name}"; + var path = binEntry.Path[^1].Equals('/') ? binEntry.Path + binEntry.Name : $"{binEntry.Path}/{binEntry.Name}"; var pattern = $"{path}/%"; var childEntries = _context.Entries.Where(x => x.Path.Trim().Equals(path) @@ -134,16 +130,16 @@ public async Task Handle(Command request, CancellationToken cancellati } } - entry.Path = entry.OldPath; - entry.OldPath = null; - entry.LastModified = localDateTimeNow; - entry.LastModifiedBy = request.CurrentUser.Id; + binEntry.Path = binEntry.OldPath; + binEntry.OldPath = null; + binEntry.LastModified = localDateTimeNow; + binEntry.LastModifiedBy = request.CurrentUser.Id; - var result = _context.Entries.Update(entry); + var result = _context.Entries.Update(binEntry); await _context.SaveChangesAsync(cancellationToken); - using (Logging.PushProperties(nameof(Entry), entry.Id, request.CurrentUser.Id)) + using (Logging.PushProperties(nameof(Entry), binEntry.Id, request.CurrentUser.Id)) { - _logger.LogRestoreBinEntry(request.CurrentUser.Username, entry.Id.ToString()); + _logger.LogRestoreBinEntry(request.CurrentUser.Username, binEntry.Id.ToString()); } return _mapper.Map(result.Entity); } diff --git a/src/Application/Entries/Commands/UpdateEntry.cs b/src/Application/Entries/Commands/UpdateEntry.cs index 7f463cb7..e8c6c007 100644 --- a/src/Application/Entries/Commands/UpdateEntry.cs +++ b/src/Application/Entries/Commands/UpdateEntry.cs @@ -24,6 +24,7 @@ public Validator() RuleFor(x => x.Name) .NotEmpty().WithMessage("Entry's name is required.") + .Matches("^[\\p{L}A-Za-z_.\\s\\-0-9]*$").WithMessage("Invalid name format.") .MaximumLength(256).WithMessage("Name cannot exceed 256 characters."); } }