public void CreateFolder_ReturnsFolderIfItIsNew() { // arrange string userId = "1234"; string name = "newFolder"; FolderVM folder = new FolderVM { Id = "1", Path = _rootPath, OwnerId = userId, ParentFolderId = null, IsShared = false }; var mock = new Mock <IUnitOfWork>(); mock.Setup(a => a.GetRepository <Folder>().Create(It.IsAny <Folder>())); FileSystemService service = new FileSystemService(mock.Object, _mapper); ElementVM expected = new ElementVM { ElemName = name, IsFolder = true, IsShared = false, LastModified = DateTime.Now.ToShortDateString(), Size = null, Type = ElementVM.FileType.Folder }; // act ElementVM result = service.CreateFolder(folder, name, userId); expected.Id = result.Id; // assert Assert.AreEqual(expected, result); }
// this method recursively compresses a folder structure private void CompressFolder(Folder folder, string userId, ZipOutputStream zipStream, int folderOffset) { List <Folder> childFolders = _database.GetRepository <Folder>().Find(f => f.ParentFolderId == folder.Id).ToList(); List <DAL.Entities.File> childFiles = _database.GetRepository <DAL.Entities.File>().Find(f => f.FolderId == folder.Id).ToList(); foreach (var childFile in childFiles) { FileVM file = new FileVM { IsShared = childFile.IsShared, OwnerId = _database.GetRepository <Folder>().Get(childFile.FolderId).OwnerId }; if (CheckAccessToView(file, userId)) { CompressFile(childFile, zipStream, folderOffset); } } foreach (var childFolder in childFolders) { FolderVM vm = new FolderVM { IsShared = childFolder.IsShared, OwnerId = childFolder.OwnerId }; if (CheckAccessToView(vm, userId)) { CompressFolder(childFolder, userId, zipStream, folderOffset); } } }
public void GetFolderById_ReturnsFolderVM() { // arrange Folder folderFromDB = new Folder { Id = "23", Path = "C:\\User\\MyFolder", OwnerId = "User", ParentFolderId = "1", IsShared = false }; var mock = new Mock <IUnitOfWork>(); mock.Setup(a => a.GetRepository <Folder>().Get("23")).Returns(folderFromDB); FileSystemService service = new FileSystemService(mock.Object, _mapper); FolderVM expected = new FolderVM { Id = "23", Path = "C:\\User\\MyFolder", OwnerId = "User", ParentFolderId = "1", IsShared = false }; // act FolderVM result = service.GetFolderById("23"); // assert Assert.AreEqual(expected, result); }
// this action returns all folders and files that are contained in the needed folder public IActionResult Watch(string folderId) { // if the user is not authenticated, redirect to login page if (folderId == null && !User.Identity.IsAuthenticated) { return(RedirectToAction("Login", "Account")); } FolderVM folder = _fileSystemService.GetFolderById(folderId); string userId = User.FindFirstValue(ClaimTypes.NameIdentifier); // check access to needed folder if (_fileSystemService.CheckAccessToView(folder, userId) || _fileSystemService.HasSharedChildren(folderId)) { List <ElementVM> elems = _fileSystemService.GetElementsFromFolder(_fileSystemService.GetFolderById(folderId), userId).ToList(); Stack <FolderShortInfoVM> folderPath = _fileSystemService.GetFolderPath(folderId, userId); WatchPageVM model = new WatchPageVM { Elements = elems, FolderPath = folderPath, CurrFolderId = folderId }; return(View(model)); } else { throw new StatusCodeException($"You don't have access to folder with ID = {folderId}.", StatusCodes.Status403Forbidden); } }
// this method removes desired files and folders public bool RemoveFilesAndFolders(string userId, string[] foldersId, string[] filesId) { bool success = true; foreach (var id in foldersId) { Folder folder = _database.GetRepository <Folder>().Get(id); if (folder == null) { throw new StatusCodeException($"The folder with ID = {id} doesn't exists.", StatusCodes.Status404NotFound); } FolderVM vm = new FolderVM { IsShared = folder.IsShared, OwnerId = folder.OwnerId }; if (CheckEditAccess(vm, userId)) { try { Directory.Delete(folder.Path, true); Folder deletedFolder = _database.GetRepository <Folder>().Get(id); RemoveChildrenFolders(deletedFolder); _database.GetRepository <Folder>().Delete(id); _database.Save(); } catch { success = false; } } } foreach (var id in filesId) { DAL.Entities.File file = _database.GetRepository <DAL.Entities.File>().Get(id); if (file == null) { throw new StatusCodeException($"The file with ID = {id} doesn't exists.", StatusCodes.Status404NotFound); } FileVM vm = new FileVM { IsShared = file.IsShared, OwnerId = _database.GetRepository <Folder>().Get(file.FolderId).OwnerId }; if (CheckEditAccess(vm, userId)) { try { System.IO.File.Delete(file.Path); _database.GetRepository <DAL.Entities.File>().Delete(id); _database.Save(); } catch { success = false; } } } return(success); }
public static Folder MapFolder(FolderVM folderVM) { var result = new Folder(); result.Id = folderVM.Id; result.Path = folderVM.Path; if (folderVM is DestinationFolderVM) { var destFolderVM = folderVM as DestinationFolderVM; result.Type = FolderType.Destination; result.NeedDevideImagesByHash = destFolderVM.NeedDevideImagesByHash; result.NeedRename = destFolderVM.NeedRename; result.IncorrectFormatSubpath = destFolderVM.IncorrectFormatSubpath; result.IncorrectHashSubpath = destFolderVM.IncorrectHashSubpath; result.NonHashSubpath = destFolderVM.NonHashSubpath; } else if (folderVM is SourceFolderVM) { var sourceFolderVM = folderVM as SourceFolderVM; result.Type = FolderType.Source; result.NeedCheckFormat = sourceFolderVM.CheckFormat; result.NeedCheckNameHash = sourceFolderVM.CheckNameHash; result.Extensions = sourceFolderVM.SupportedExtensionsRaw.ToList(); result.TagsFromSubfoder = sourceFolderVM.TagsFromSubfolder; result.AddTagFromFileName = sourceFolderVM.AddTagFromFileName; } return(result); }
// this method returns folder by id public FolderVM GetFolderById(string id) { FolderVM folder = _mapper.Map <Folder, FolderVM>(_database.GetRepository <Folder>().Get(id)); if (folder == null) { throw new StatusCodeException($"The folder with ID = {id} doesn't exists.", StatusCodes.Status404NotFound); } return(folder); }
// this method checks the current user for editing access to the needed folder public bool CheckEditAccess(FolderVM folder, string currentId) { if (folder == null) { throw new StatusCodeException("Unable to check access to the folder.", StatusCodes.Status500InternalServerError); } if (folder.OwnerId == currentId) { return(true); } return(false); }
public void CheckEditAccess_Returns500StatusCodeIfFolderIsNull() { // arrange string currUserId = "4321"; FolderVM folder = null; var mock = new Mock <IUnitOfWork>(); FileSystemService service = new FileSystemService(mock.Object, _mapper); int expected = 500; // act StatusCodeException ex = Assert.Throws <StatusCodeException>(() => service.CheckEditAccess(folder, currUserId)); // assert Assert.AreEqual(expected, ex.Data["Status code"]); }
public void CheckAccessToView_ReturnsTrueIfFolderIsNonSharedButYouAreOwner() { // arrange string currUserId = "4321"; FolderVM folder = new FolderVM { IsShared = false, OwnerId = currUserId }; var mock = new Mock <IUnitOfWork>(); FileSystemService service = new FileSystemService(mock.Object, _mapper); // act bool result = service.CheckAccessToView(folder, currUserId); // assert Assert.IsTrue(result); }
public void CheckEditAccess_ReturnsFalseIfYouAreNotFolderOwner() { // arrange string currUserId = "4321"; FolderVM folder = new FolderVM { IsShared = true, OwnerId = "1234" }; var mock = new Mock <IUnitOfWork>(); FileSystemService service = new FileSystemService(mock.Object, _mapper); // act bool result = service.CheckEditAccess(folder, currUserId); // assert Assert.IsFalse(result); }
// this method checks access to view the needed folder by current user public bool CheckAccessToView(FolderVM folder, string currentId) { if (folder == null) { throw new StatusCodeException("Unable to check access to the folder.", StatusCodes.Status500InternalServerError); } if (folder.IsShared) { return(true); } else { return(CheckEditAccess(folder, currentId)); } }
// this method creates an archive and returns it for download public MemoryStream CreateArchive(string currFolderId, string userId, string[] foldersId, string[] filesId) { Folder parentFolder = _database.GetRepository <Folder>().Get(currFolderId); if (parentFolder == null) { throw new StatusCodeException($"Invalid current folder ID ({currFolderId}). Unable to create archive.", StatusCodes.Status500InternalServerError); } ZipStrings.UseUnicode = true; MemoryStream outputMemStream = new MemoryStream(); using (var zipStream = new ZipOutputStream(outputMemStream)) { zipStream.SetLevel(0); int folderOffset = parentFolder.Path.Length + (parentFolder.Path.EndsWith("\\") ? 0 : 1); foreach (var id in filesId) { DAL.Entities.File file = _database.GetRepository <DAL.Entities.File>().Get(id); FileVM vm = new FileVM { IsShared = file.IsShared, OwnerId = _database.GetRepository <Folder>().Get(file.FolderId).OwnerId }; if (CheckAccessToView(vm, userId)) { CompressFile(file, zipStream, folderOffset); } } foreach (var id in foldersId) { Folder folder = _database.GetRepository <Folder>().Get(id); FolderVM vm = new FolderVM { IsShared = folder.IsShared, OwnerId = folder.OwnerId }; if (CheckAccessToView(vm, userId)) { CompressFolder(folder, userId, zipStream, folderOffset); } } zipStream.IsStreamOwner = false; } outputMemStream.Position = 0; return(outputMemStream); }
public void CreateFolder_Returns500StatusCodeIfParentIsNull() { // arrange string userId = "1234"; string name = "newFolder"; FolderVM folder = null; var mock = new Mock <IUnitOfWork>(); mock.Setup(a => a.GetRepository <Folder>().Create(It.IsAny <Folder>())); FileSystemService service = new FileSystemService(mock.Object, _mapper); int expected = 500; // act StatusCodeException ex = Assert.Throws <StatusCodeException>(() => service.CreateFolder(folder, name, userId)); // assert Assert.AreEqual(expected, ex.Data["Status code"]); }
/// <summary> /// Updates the existing folder. /// </summary> public async Task <FolderTitleVM> UpdateAsync(string key, FolderVM vm) { await ValidateAsync(vm, key); var folder = await _db.Folders .Include(x => x.Tags) .FirstOrDefaultAsync(x => x.Key == key); if (folder.Slug != vm.Slug) { // update paths in subfolders var oldPath = folder.Path; var newPath = PathHelper.Combine(PathHelper.GetParentPath(folder.Path), vm.Slug); folder.Path = newPath; var subfolders = await _db.Folders .Where(x => x.Path.StartsWith(oldPath) && x.Depth > folder.Depth) .ToListAsync(); foreach (var subfolder in subfolders) { subfolder.Path = newPath + subfolder.Path.Substring(oldPath.Length); } } _mapper.Map(vm, folder); var oldTags = folder.Tags?.Select(x => x.TagId).OrderBy(x => x).ToList() ?? new List <int>(); var newTags = vm.Tags?.OrderBy(x => x).ToList() ?? new List <int>(); folder.Tags = vm.Tags?.Select(x => new FolderTagBinding { TagId = x }).ToList(); await _db.SaveChangesAsync(); if (!oldTags.SequenceEqual(newTags)) { await _jobSvc.RunAsync(JobBuilder.For <RebuildInheritedTagsJob>().SupersedeAll()); // sic! run in background } return(_mapper.Map <FolderTitleVM>(folder)); }
public void CreateFolder_ReturnsNullIfFolderAlreadyExists() { // arrange string userId = "1234"; string name = "ExistsFolder"; FolderVM folder = new FolderVM { Id = "1", Path = _rootPath, OwnerId = userId, ParentFolderId = null, IsShared = false }; var mock = new Mock <IUnitOfWork>(); mock.Setup(a => a.GetRepository <Folder>().Create(It.IsAny <Folder>())); FileSystemService service = new FileSystemService(mock.Object, _mapper); // act ElementVM result = service.CreateFolder(folder, name, userId); // assert Assert.IsNull(result); }
public void CreateFolder_CreatesFolderInDB() { // arrange string userId = "1234"; string name = "newFolder"; FolderVM folder = new FolderVM { Id = "1", Path = _rootPath, OwnerId = userId, ParentFolderId = null, IsShared = false }; var mock = new Mock <IUnitOfWork>(); mock.Setup(a => a.GetRepository <Folder>().Create(It.IsAny <Folder>())); FileSystemService service = new FileSystemService(mock.Object, _mapper); // act service.CreateFolder(folder, name, userId); mock.Verify(a => a.GetRepository <Folder>().Create(It.IsAny <Folder>()), Times.Once); // assert Assert.IsTrue(true); }
/// <summary> /// Adds a new folder. /// </summary> public async Task <FolderTitleVM> CreateAsync(string parentKey, FolderVM vm) { await ValidateAsync(vm, null, parentKey); var parent = await GetParentFolderAsync(parentKey); var folder = _mapper.Map <Folder>(vm); folder.Key = UniqueKey.Get(); folder.Depth = parent.Depth + 1; folder.Path = PathHelper.Combine(parent.Path, folder.Slug); folder.Tags = vm.Tags?.Select(x => new FolderTagBinding { TagId = x }).ToList(); _db.Folders.Add(folder); await _db.SaveChangesAsync(); return(_mapper.Map <FolderTitleVM>(folder)); }
public void CreateFolder_CreatesFolderOnHardDrive() { // arrange string userId = "1234"; string name = "newFolder"; FolderVM folder = new FolderVM { Id = "1", Path = _rootPath, OwnerId = userId, ParentFolderId = null, IsShared = false }; var mock = new Mock <IUnitOfWork>(); mock.Setup(a => a.GetRepository <Folder>().Create(It.IsAny <Folder>())); FileSystemService service = new FileSystemService(mock.Object, _mapper); // act service.CreateFolder(folder, name, userId); System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(_rootPath + "\\" + name); bool result = info.Exists; // assert Assert.IsTrue(result); }
// this method return path to current folder as list public Stack <FolderShortInfoVM> GetFolderPath(string currFolderId, string userId) { Stack <FolderShortInfoVM> folderPath = new Stack <FolderShortInfoVM>(); bool rootFolder = false; do { Folder folder = _database.GetRepository <Folder>().Get(currFolderId); if (folder == null) { throw new StatusCodeException("Unable to define folder path.", StatusCodes.Status500InternalServerError); } FolderVM vm = new FolderVM { IsShared = folder.IsShared, OwnerId = folder.OwnerId }; if (CheckAccessToView(vm, userId) || HasSharedChildren(currFolderId)) { FolderShortInfoVM folderInfo = new FolderShortInfoVM { Id = folder.Id, Name = ElementHelperClass.DefineFileName(folder.Path) }; currFolderId = folder.ParentFolderId; if (folder.ParentFolderId == null) { rootFolder = true; folderInfo.Name = "Your drive"; } folderPath.Push(folderInfo); } else { rootFolder = true; } } while (!rootFolder); return(folderPath); }
// this method creates a new folder on the hard drive, saves it in the database and return it public ElementVM CreateFolder(FolderVM parentFolder, string name, string ownerId) { if (parentFolder == null) { throw new StatusCodeException("Unable to create new folder.", StatusCodes.Status500InternalServerError); } string newFolderPath = parentFolder.Path + '\\' + name; if (!Directory.Exists(newFolderPath)) { Directory.CreateDirectory(newFolderPath); Folder newFolder = new Folder { Id = Guid.NewGuid().ToString(), Path = newFolderPath, IsShared = parentFolder.IsShared, OwnerId = ownerId, ParentFolderId = parentFolder.Id }; _database.GetRepository <Folder>().Create(newFolder); _database.Save(); ElementVM model = new ElementVM { Id = newFolder.Id, IsFolder = true, Type = ElementVM.FileType.Folder, ElemName = name, LastModified = DateTime.Now.ToShortDateString(), Size = null }; return(model); } return(null); }
/// <summary> /// Ensures that the folder details are valid. /// </summary> private async Task ValidateAsync(FolderVM vm, string key, string parentKey = null) { if (string.IsNullOrEmpty(vm.Caption)) { throw new OperationException("Caption is required."); } if (string.IsNullOrEmpty(vm.Slug)) { throw new OperationException("Slug is required."); } if (!Regex.IsMatch(vm.Slug, "^[a-z0-9-]+$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)) { throw new OperationException("Slug contains invalid characters. Only English letters, numbers and a hyphen are allowed."); } if (!string.IsNullOrEmpty(vm.ThumbnailKey)) { var exists = await _db.Media.AnyAsync(x => x.Key == vm.ThumbnailKey); if (!exists) { throw new OperationException($"Media '{vm.ThumbnailKey}' does not exist."); } } var neighbours = await GetNeighboursAsync(); foreach (var n in neighbours) { if (n.Caption.Equals(vm.Caption, StringComparison.InvariantCultureIgnoreCase)) { throw new OperationException($"Folder with caption '{vm.Caption}' already exists nearby."); } if (n.Slug.Equals(vm.Slug, StringComparison.InvariantCultureIgnoreCase)) { throw new OperationException($"Folder with slug '{vm.Slug}' already exists nearby."); } } if (vm.Tags?.Length > 0) { var tags = await _db.Tags .Where(x => vm.Tags.Contains(x.Id)) .Select(x => x.Id) .ToHashSetAsync(); var missingTags = vm.Tags.Where(x => !tags.Contains(x)).ToList(); if (missingTags.Any()) { throw new OperationException($"Tag(s) {missingTags.JoinString(", ")} do not exists."); } } async Task <IReadOnlyList <Folder> > GetNeighboursAsync() { if (string.IsNullOrEmpty(key)) { var parent = await GetParentFolderAsync(parentKey); return(await _db.Folders .AsNoTracking() .Where(x => x.Path.StartsWith(parent.Path) && x.Depth == parent.Depth + 1) .ToListAsync()); } else { var folder = await _db.Folders .AsNoTracking() .FirstOrDefaultAsync(x => x.Key == key); if (folder == null) { throw new OperationException($"Folder '{key}' does not exist."); } var parentPath = PathHelper.GetParentPath(folder.Path); return(await _db.Folders .AsNoTracking() .Where(x => x.Path.StartsWith(parentPath) && x.Depth == folder.Depth && x.Key != key) .ToListAsync()); } } }
// this method upload files on the hard drive and saves them in the database public async Task <ICollection <ElementVM> > UploadFiles(IFormFileCollection files, FolderVM parentFolder) { List <ElementVM> elements = new List <ElementVM>(); foreach (var uploadedFile in files) { string path = parentFolder.Path + '\\' + uploadedFile.FileName; if (!System.IO.File.Exists(path)) { DAL.Entities.File file = new DAL.Entities.File { Id = Guid.NewGuid().ToString(), Path = path, IsShared = parentFolder.IsShared, FolderId = parentFolder.Id }; _database.GetRepository <DAL.Entities.File>().Create(file); ElementVM elem = new ElementVM { Id = file.Id, IsFolder = false, ElemName = uploadedFile.FileName, LastModified = DateTime.Now.ToShortDateString(), Type = ElementHelperClass.DefineFileType(ElementHelperClass.DefineFileExtension(uploadedFile.FileName)), Size = ElementHelperClass.Recount(new Tuple <double, ElementVM.Unit>(uploadedFile.Length, ElementVM.Unit.B)), IsShared = file.IsShared }; elements.Add(elem); } using (var fileStream = new FileStream(path, FileMode.Create)) { await uploadedFile.CopyToAsync(fileStream); } } _database.Save(); return(elements); }
public Task Update(string key, [FromBody] FolderVM vm) { return(_folderMgr.UpdateAsync(key, vm)); }
// this method returns all folders and files that are contained in the needed folder public ICollection <ElementVM> GetElementsFromFolder(FolderVM folderVM, string userId) { if (folderVM == null) { throw new StatusCodeException("The needed folder doesn't exists.", StatusCodes.Status404NotFound); } DirectoryInfo dir = new DirectoryInfo(folderVM.Path); FileInfo[] files; DirectoryInfo[] dirs; files = dir.GetFiles(); dirs = dir.GetDirectories(); List <ElementVM> models = new List <ElementVM>(); List <Folder> childFolders = _database.GetRepository <Folder>().Find(f => f.ParentFolderId == folderVM.Id).ToList(); List <DAL.Entities.File> childFiles = _database.GetRepository <DAL.Entities.File>().Find(f => f.FolderId == folderVM.Id).ToList(); foreach (var elem in dirs) { Folder folder = childFolders.Find(f => f.Path == elem.FullName); if (folder != null) { if (CheckAccessToView(new FolderVM { OwnerId = folder.OwnerId, IsShared = folder.IsShared }, userId)) { ElementVM model = new ElementVM { Id = folder.Id, IsFolder = true, Type = ElementVM.FileType.Folder, ElemName = elem.Name, LastModified = elem.LastWriteTime.ToShortDateString(), Size = null, IsShared = folder.IsShared }; models.Add(model); } } } foreach (var elem in files) { DAL.Entities.File file = childFiles.Find(f => f.Path == elem.FullName); if (file != null) { FileVM vm = new FileVM { IsShared = file.IsShared, OwnerId = _database.GetRepository <Folder>().Get(file.FolderId).OwnerId }; if (CheckAccessToView(vm, userId)) { // for a more convenient display of file size, call the conversion function Tuple <double, ElementVM.Unit> size = new Tuple <double, ElementVM.Unit>(elem.Length, ElementVM.Unit.B); size = ElementHelperClass.Recount(size); ElementVM.FileType type = ElementHelperClass.DefineFileType(elem.Extension); ElementVM model = new ElementVM { Id = childFiles.Find(f => f.Path == elem.FullName).Id, IsFolder = false, Type = type, ElemName = elem.Name, LastModified = elem.LastWriteTime.ToShortDateString(), Size = size, IsShared = file.IsShared }; models.Add(model); } } } return(models); }
public Task <FolderTitleVM> Create(string key, [FromBody] FolderVM vm) { return(_folderMgr.CreateAsync(key, vm)); }
// this method changes access to view for the selected folders and files and returns folder id public string ChangeAccess(string currFolderId, string userId, string[] foldersId, string[] filesId, bool openAccess) { Folder parent = _database.GetRepository <Folder>().Get(currFolderId); if (parent == null) { throw new StatusCodeException($"The folder with ID = {currFolderId} doesn't exists.", StatusCodes.Status404NotFound); } FolderVM parentVM = new FolderVM { IsShared = parent.IsShared, OwnerId = parent.OwnerId }; if (CheckEditAccess(parentVM, userId)) { string idForLink; if (foldersId.Length == 1 && filesId.Length == 0) { idForLink = foldersId[0]; } else { idForLink = currFolderId; } foreach (string id in filesId) { DAL.Entities.File file = _database.GetRepository <DAL.Entities.File>().Get(id); if (file == null) { throw new StatusCodeException($"The file with ID = {id} doesn't exists.", StatusCodes.Status404NotFound); } FileVM vm = new FileVM { IsShared = file.IsShared, OwnerId = _database.GetRepository <Folder>().Get(file.FolderId).OwnerId }; if (CheckEditAccess(vm, userId)) { file.IsShared = openAccess; _database.GetRepository <DAL.Entities.File>().Update(file); } } foreach (string id in foldersId) { Folder folder = _database.GetRepository <Folder>().Get(id); if (folder == null) { throw new StatusCodeException($"The folder with ID = {id} doesn't exists.", StatusCodes.Status404NotFound); } FolderVM vm = new FolderVM { IsShared = folder.IsShared, OwnerId = folder.OwnerId }; if (CheckEditAccess(vm, userId)) { folder.IsShared = openAccess; _database.GetRepository <Folder>().Update(folder); ChangeChildrenAccess(folder, openAccess); } } _database.Save(); return(idForLink); } else { throw new StatusCodeException($"You don't have access to folder with ID = {currFolderId}.", StatusCodes.Status403Forbidden); } }