예제 #1
0
        public JsonResult Children(
            FileNode target,
            [FromQuery]int index = 0,
            [FromQuery]int length = 10,
            [FromQuery]OrderTypes order = OrderTypes.DirFirst) {
            if (!target.HasReadAuthority(User, Database)) {
                throw new AuthorizeException("無權限存取該目標");
            }
            if (target.IsFile) throw new ApiInvalidOperationException("檔案無子系");

            var data = target.GetChildren(Database);

            if (order == OrderTypes.DirFirst) {
                data = from t in data
                       orderby t.IsFile, t.Ext, t.Name
                       select t;
            } else if (order == OrderTypes.FileFirst) {
                data = from t in data
                       orderby t.IsFile, t.Ext descending, t.Name
                       select t;
            }

            var result = new ApiResult() {
                Result = data.Skip(index).Take(length)
            };
            result.Type.Index = index;
            result.Type.Length = length;
            result.Type.Count = data.Count();

            return result;
        }
예제 #2
0
 public JsonResult Info(FileNode target) {
     if (!target.HasReadAuthority(User, Database)) {
         throw new AuthorizeException("無權限存取該目標");
     }
     return new ApiResult() {
         Result = target
     };
 }
예제 #3
0
        public JsonResult Clear(
            FileNode target,
            [FromForm]List<FileNodeNullableProperties> properties) {
            if (!target.HasWriteAuthority(User, Database)) {
                throw new AuthorizeException("無權限進行變更");
            }

            foreach (var property in properties) {
                if (property == FileNodeNullableProperties.Description) {
                    target.Description = null;
                } else if (property == FileNodeNullableProperties.DirMaxSize) {
                    if (target.IsFile) continue;
                } else if (property == FileNodeNullableProperties.Group) {
                    if (target.OwnerId == User.Id) target.GroupId = null;
                }
            }

            Database.SaveChanges();
            return new ApiResult() {
                Result = target
            };
        }
예제 #4
0
 public JsonResult Delete(FileNode target) {
     if (target == null) throw new ApiArgumentException($"{nameof(target)}不應該為null");
     if (!target.HasWriteAuthority(User, Database)) {
         throw new AuthorizeException("無權限存取該目錄");
     }
     if (target.ParentId == null) throw new ApiInvalidOperationException("使用者根目錄不得刪除");
     target.Delete(Database);
     return new ApiResult();
 }
예제 #5
0
        /// <summary>
        /// 新增子目錄節點
        /// </summary>
        /// <param name="parent">父節點</param>
        /// <param name="dirName"></param>
        /// <returns></returns>
        protected async Task<JsonResult> CreateDir(
            FileNode parent,
            [FromForm]string dirName) {
            FileNode child = await parent.CreateChildrenAsync(dirName, Database);

            var parentList = child.GetParentChain(Database);
            foreach (var p in parentList) p.Datetime = child.Datetime;
            await Database.SaveChangesAsync();

            return new ApiResult() {
                Result = child
            };
        }
예제 #6
0
        public JsonResult Put(
            FileNode target,
            FileNode parent,
            [FromForm]string name = null,
            [FromForm]string description = null,
            [FromForm]long? dirMaxSize = null,
            [FromForm]Group group = null,
            [FromForm]FileNodeAuthority? groupAuthority = null,
            [FromForm]FileNodeAuthority? otherAuthority = null
            ) {
            if (!target.HasWriteAuthority(User, Database)) {
                throw new AuthorizeException("無權限進行變更");
            }

            //是目錄,且非擁有者禁止調整
            if (!target.IsFile && target.Owner != User) {
                throw new AuthorizeException("僅目錄所有者可進行變更");
            }

            #region 非擁有者僅可變更檔案的名稱與敘述
            if (name != null) target.Name = name;
            if (description != null) target.Description = description;
            if (!target.IsFile && dirMaxSize.HasValue) target.DirMaxSize = dirMaxSize;
            #endregion

            if (target.Owner == User) {//以下屬性僅擁有者
                if (parent != null && target.ParentId != null) {
                    target.ParentId = parent.Id;//僅非根目錄可移動
                }
                if (group != null) target.Group = group;
                if (groupAuthority.HasValue) target.GroupAuthority = groupAuthority.Value;
                if (otherAuthority.HasValue) target.OtherAuthority = otherAuthority.Value;
            }

            Database.SaveChanges();
            return new ApiResult() {
                Result = target
            };
        }
예제 #7
0
        public async Task<JsonResult> Post(
            FileNode target = null,
            [FromForm]IFormFile[] files = null,
            [FromForm]string dirName = "未命名資料夾") {
            if (!IsLogin && target == null) throw new ApiInvalidOperationException("未登入狀態必須要指定目錄");
            if (target == null) {//預設上傳到目前使用者根目錄
                target = User.GetRootFileNode(Database);
            }
            if (target.IsFile) throw new ApiInvalidOperationException($"目標節點不應該為檔案");

            if (!target.HasWriteAuthority(User, Database)) {
                throw new AuthorizeException("無權限存取該目錄");
            }

            if (files != null && files.Count() > 0) {//上傳檔案至指定目錄
                return await UploadFile(target, files);
            } else if (target.Owner == User) {
                return await CreateDir(target, dirName);
            }
            throw new AuthorizeException("僅目錄擁有者可以建立子系目錄目錄");
        }
예제 #8
0
 /// <summary>
 /// 上傳檔案至指定檔案節點
 /// </summary>
 /// <param name="parent">父目錄</param>
 /// <param name="files">檔案集合</param>
 /// <returns></returns>
 protected async Task<JsonResult> UploadFile(
     FileNode parent,
     IFormFile[] files) {
     List<FileNode> result = new List<FileNode>();
     foreach (var file in files) {
         result.Add(await parent.CreateChildrenAsync(file, Database));
     }
     return new ApiResult() {
         Result = result.ToArray()
     };
 }
예제 #9
0
        public JsonResult GeneratePreviewKey(FileNode target) {
            if (!target.HasReadAuthority(User, Database)) {
                throw new AuthorizeException("無權限存取該目標");
            }
            if (!target.IsFile) throw new ApiInvalidOperationException($"目標節點不應該為目錄");

            var ExpireTime = DateTime.Now.AddMinutes(10);
            Guid Key = PreviewKeyCheck.Create(target.Id, ExpireTime);

            var result = new ApiResult() {
                Result = new {
                    TargetId = target.Id,
                    Key = Key,
                    ExpireTime = ExpireTime
                }
            };
            result.Type.Name = "PreviewKey";
            return result;
        }
예제 #10
0
 public FileStreamResult Preview(
     FileNode target,
     Guid key) {
     if (!PreviewKeyCheck.Check(target.Id, key)) {
         throw new AuthorizeException("錯誤的Key,請確認該Key未過期且尚未使用過");
     }
     return File(target.GetFileStream(), target.ContentType, $"{target.Name}.{target.Ext}");
 }
예제 #11
0
        public FileStreamResult Download(FileNode target) {
            if (!target.HasReadAuthority(User, Database)) {
                throw new AuthorizeException("無權限存取該目標");
            }
            target.Download++;
            Database.SaveChanges();
            if (target.IsFile) {
                return File(target.GetFileStream(), target.ContentType, target.FullName);
            } else {
                var FilePath = target.GetAndCreateDirZipFileRealPath(User, Database);
                Response.OnCompleted(async (filePath) => {
                    System.IO.File.Delete((string)filePath);
                },FilePath);

                return File(
                    new FileStream(FilePath, FileMode.Open),
                    "application/zip", 
                    $"{target.Name}.zip");
            }
        }
예제 #12
0
        public JsonResult Search(
            FileNode target = null,
            [FromQuery]string keyword = "",
            [FromQuery]int index = 0,
            [FromQuery]int length = 10,
            [FromQuery]OrderTypes order = OrderTypes.DirFirst) {
            if (target == null && !IsLogin) throw new AuthorizeException();
            if (target == null) {
                target = User.GetRootFileNode(Database);
            }
            if (target.IsFile) throw new ApiInvalidOperationException("檔案無子系");

            if (!target.HasReadAuthority(User, Database)) {
                throw new AuthorizeException("無權限存取該目標");
            }


            IQueryable<FileNode> data = Database.FileNode.Where(x => x.OwnerId == User.Id).Where(x => x.Name.Contains(keyword));
            if (target != null) {
                data = from t in Database.FileNode
                       where t.ParentId == target.Id && t.Name.Contains(keyword)
                       select t;
            }

            if (order == OrderTypes.DirFirst) {
                data = from t in data
                       orderby t.IsFile, t.Ext, t.Name
                       select t;
            } else if (order == OrderTypes.FileFirst) {
                data = from t in data
                       orderby t.IsFile, t.Ext descending, t.Name
                       select t;
            }

            var result = new ApiResult() {
                Result = data.Skip(index).Take(length)
            };
            result.Type.Index = index;
            result.Type.Length = length;
            result.Type.Count = data.Count();
            return result;
        }
예제 #13
0
        [Authorize("AdminOnly")]//僅管理員擁有權限
        public JsonResult AddUser(
            [FromForm]string id,
            [FromForm]string password = "******",
            [FromForm]UserAuthority authority = UserAuthority.User,
            [FromForm]long spaceSize = 0) {
            if (string.IsNullOrWhiteSpace(id)) {
                throw new ApiArgumentException($"參數{nameof(id)}不該為空字串或null");
            }

            User newUser = new User() {
                Id = id,
                Authority = UserAuthority.User,
                Name = id,
                SpaceSize = spaceSize == -1 ? null : (long?)spaceSize
            };
            if (newUser.Authority == UserAuthority.Admin) newUser.SpaceSize = null;
            newUser.SetPassword(password);
            Database.User.Add(newUser);

            var rootNode = new FileNode() { Owner = newUser, Name = id };
            Database.FileNode.Add(rootNode);
            Database.SaveChanges();

            return new ApiResult() {
                Result = newUser
            };
        }
예제 #14
0
        /// <summary>
        /// 建立目錄節點
        /// </summary>
        /// <param name="Name">目錄名稱</param>
        /// <param name="Database">資料庫</param>
        /// <returns></returns>
        public async Task<FileNode> CreateChildrenAsync(string Name, SharpDiskDbContext Database) {
            FileNode child = new FileNode() {
                Name = Name,
                Datetime = DateTime.Now,
                Parent = this,
                Owner = this.Owner,
                IsFile = false,
                GroupId = this.GroupId,
                GroupAuthority = this.GroupAuthority,
                OtherAuthority = this.OtherAuthority
            };

            Database.FileNode.Add(child);
            await Database.SaveChangesAsync();

            return child;
        }
예제 #15
0
        /// <summary>
        /// 建立檔案節點
        /// </summary>
        /// <param name="File">檔案</param>
        /// <param name="Database">資料庫</param>
        /// <returns></returns>
        public async Task<FileNode> CreateChildrenAsync(IFormFile File, SharpDiskDbContext Database) {
            FileNode newFile = new FileNode();

            #region 空間檢查
            if (//使用者空間不足
                Owner.SpaceSize.HasValue &&//有空間限制
                Owner.GetTotalUsedSpace(Database) + File.Length > Owner.SpaceSize) {
                throw new LackOfSpaceException($"目前使用者空間不足");
            }

            //檢查目錄鍊容量是否足夠
            var ParentChain = this.GetParentChain(Database);
            ParentChain.Insert(0, this);
            var TooSmail = ParentChain.Where(x =>
                x.DirMaxSize.HasValue && x.Size + File.Length > x.DirMaxSize
            );
            if (TooSmail.Count() > 0) {
                throw new LackOfSpaceException($"達到父系目錄限制大小:{string.Join(",", TooSmail.Select(x => x.Name))}");
            }
            DateTime now = DateTime.Now;
            foreach (var node in ParentChain) {
                node.Size += File.Length;
                node.Datetime = now;
            }
            #endregion

            #region 儲存檔案
            try {
                using (FileStream fileStream = System.IO.File.Create(Startup.FilesDirPath + newFile.Id)) {
                    await File.OpenReadStream().CopyToAsync(fileStream);
                    await fileStream.FlushAsync();
                }
            } catch (Exception e) {
                throw new UnknowException(e.Message);
            }
            #endregion

            #region FileNode建構
            newFile.IsFile = true;
            newFile.Owner = Owner;

            newFile.GroupId = this.GroupId;//上傳後的檔案權限繼承
            newFile.GroupAuthority = this.GroupAuthority;
            newFile.OtherAuthority = this.OtherAuthority;

            newFile.Parent = this;
            newFile.Size = File.Length;
            newFile.ContentType = File.ContentType;
            newFile.Ext = File.FileName.Split('.').LastOrDefault();
            newFile.Datetime = DateTime.Now;
            newFile.Name = File.FileName.Substring(0, File.FileName.LastIndexOf("."));
            #endregion

            Database.FileNode.Add(newFile);
            Database.SaveChanges();
            return newFile;
        }