public FoldersModule( TenantManager tenantManager, UserManager userManager, WebItemSecurity webItemSecurity, FilesLinkUtility filesLinkUtility, FileSecurity fileSecurity, IDaoFactory daoFactory) : base(tenantManager, webItemSecurity) { UserManager = userManager; FilesLinkUtility = filesLinkUtility; FileSecurity = fileSecurity; FolderDao = daoFactory.GetFolderDao <int>(); }
private IEnumerable <FileEntry> Filter(IEnumerable <FileEntry> entries, FilesSecurityActions action, Guid userId) { if (entries == null || !entries.Any()) { return(Enumerable.Empty <FileEntry>()); } entries = entries.Where(f => f != null); var result = new List <FileEntry>(entries.Count()); // save entries order var order = entries.Select((f, i) => new { Id = f.UniqID, Pos = i }).ToDictionary(e => e.Id, e => e.Pos); // common or my files Func <FileEntry, bool> filter = f => f.RootFolderType == FolderType.COMMON || f.RootFolderType == FolderType.USER || f.RootFolderType == FolderType.SHARE; if (entries.Any(filter)) { var subjects = GetUserSubjects(userId); List <FileShareRecord> shares = null; foreach (var e in entries.Where(filter)) { if (!CoreContext.Authentication.GetAccountByID(userId).IsAuthenticated&& userId != FileConstant.ShareLinkId) { continue; } if (action != FilesSecurityActions.Read && e is Folder && ((Folder)e).FolderType == FolderType.SHARE) { // Root Share folder read-only continue; } if (e.RootFolderType == FolderType.USER && e.RootFolderCreator == userId) { // user has all right in his folder result.Add(e); continue; } if (DefaultCommonShare == FileShare.Read && action == FilesSecurityActions.Read && e is Folder && ((Folder)e).FolderType == FolderType.COMMON) { // all can read Common folder result.Add(e); continue; } if (action == FilesSecurityActions.Read && e is Folder && ((Folder)e).FolderType == FolderType.SHARE) { // all can read Share folder result.Add(e); continue; } if (e.RootFolderType == FolderType.COMMON && IsAdministrator(userId)) { // administrator in Common has all right result.Add(e); continue; } if (shares == null) { shares = GetShares(entries.ToArray()).Join(subjects, r => r.Subject, s => s, (r, s) => r).ToList(); // shares ordered by level } FileShareRecord ace; if (e is File) { ace = shares .OrderBy(r => subjects.IndexOf(r.Subject)) .FirstOrDefault(r => Equals(r.EntryId, e.ID) && r.EntryType == FileEntryType.File); if (ace == null) { // share on parent folders ace = shares.Where(r => Equals(r.EntryId, ((File)e).FolderID) && r.EntryType == FileEntryType.Folder) .OrderBy(r => subjects.IndexOf(r.Subject)) .ThenBy(r => r.Level) .ThenByDescending(r => r.Share) .FirstOrDefault(); } } else { ace = shares.Where(r => Equals(r.EntryId, e.ID) && r.EntryType == FileEntryType.Folder) .OrderBy(r => subjects.IndexOf(r.Subject)) .ThenBy(r => r.Level) .ThenByDescending(r => r.Share) .FirstOrDefault(); } var defaultShare = e.RootFolderType == FolderType.USER ? DefaultMyShare : DefaultCommonShare; e.Access = ace != null ? ace.Share : defaultShare; if (action == FilesSecurityActions.Read && e.Access <= FileShare.Read) { result.Add(e); } else if (action == FilesSecurityActions.Edit && e.Access <= FileShare.ReadWrite) { result.Add(e); } else if (action == FilesSecurityActions.Create && e.Access <= FileShare.ReadWrite) { result.Add(e); } // can't delete in My other people's files else if (action == FilesSecurityActions.Delete && e.Access <= FileShare.ReadWrite && e.RootFolderType == FolderType.COMMON) { result.Add(e); } else if (e.Access <= FileShare.Read && e.CreateBy == userId) { result.Add(e); } if (e.CreateBy == userId) { e.Access = FileShare.None; //HACK: for client } } } // files in bunch filter = f => f.RootFolderType == FolderType.BUNCH; if (entries.Any(filter)) { using (var dao = daoFactory.GetFolderDao()) { var findedAdapters = new Dictionary <object, IFileSecurity>(); foreach (var e in entries.Where(filter)) { IFileSecurity adapter = null; if (!findedAdapters.ContainsKey(e.RootFolderId)) { var root = dao.GetFolder(e.RootFolderId); if (root != null) { adapter = FilesIntegration.GetFileSecurity(root.Title); } findedAdapters[e.RootFolderId] = adapter; } adapter = findedAdapters[e.RootFolderId]; if (adapter != null) { if (action == FilesSecurityActions.Create && adapter.CanCreate(e, userId)) { result.Add(e); } if (action == FilesSecurityActions.Delete && adapter.CanDelete(e, userId)) { result.Add(e); } if (action == FilesSecurityActions.Read && adapter.CanRead(e, userId)) { result.Add(e); } if (action == FilesSecurityActions.Edit && adapter.CanEdit(e, userId)) { result.Add(e); } } } } } // files in trash filter = f => f.RootFolderType == FolderType.TRASH; if (entries.Any(filter)) { using (var dao = daoFactory.GetFolderDao()) { var mytrashId = dao.GetFolderID(FileConstant.ModuleId, "trash", userId.ToString(), false); foreach (var e in entries.Where(filter)) { // only in my trash if (Equals(e.RootFolderId, mytrashId)) { result.Add(e); } } } } if (IsAdministrator(userId)) { // administrator can work with crashed entries (crash in files_folder_tree) filter = f => f.RootFolderType == FolderType.DEFAULT; result.AddRange(entries.Where(filter)); } // restore entries order result.Sort((x, y) => order[x.UniqID].CompareTo(order[y.UniqID])); return(result); }