private List <Tuple <FileEntry <T>, bool> > Can <T>(IEnumerable <FileEntry <T> > entry, Guid userId, FilesSecurityActions action) { var filtres = Filter(entry, action, userId); return(entry.Select(r => new Tuple <FileEntry <T>, bool>(r, filtres.Any(a => a.ID.Equals(r.ID)))).ToList()); }
private IEnumerable <FileEntry <T> > Filter <T>(IEnumerable <FileEntry <T> > entries, FilesSecurityActions action, Guid userId) { if (entries == null || !entries.Any()) { return(Enumerable.Empty <FileEntry <T> >()); } var user = UserManager.GetUsers(userId); var isOutsider = user.IsOutsider(UserManager); if (isOutsider && action != FilesSecurityActions.Read) { return(Enumerable.Empty <FileEntry <T> >()); } entries = entries.Where(f => f != null).ToList(); var result = new List <FileEntry <T> >(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 <T>, bool> filter = f => f.RootFolderType == FolderType.COMMON || f.RootFolderType == FolderType.USER || f.RootFolderType == FolderType.SHARE || f.RootFolderType == FolderType.Recent || f.RootFolderType == FolderType.Favorites || f.RootFolderType == FolderType.Templates || f.RootFolderType == FolderType.Privacy || f.RootFolderType == FolderType.Projects; var isVisitor = user.IsVisitor(UserManager); if (entries.Any(filter)) { var subjects = GetUserSubjects(userId); List <FileShareRecord> shares = null; foreach (var e in entries.Where(filter)) { if (!AuthManager.GetAccountByID(TenantManager.GetCurrentTenant().TenantId, userId).IsAuthenticated&& userId != FileConstant.ShareLinkId) { continue; } if (isOutsider && (e.RootFolderType == FolderType.USER || e.RootFolderType == FolderType.SHARE || e.RootFolderType == FolderType.Privacy)) { continue; } if (isVisitor && e.RootFolderType == FolderType.Recent) { continue; } if (isVisitor && e.RootFolderType == FolderType.Favorites) { continue; } if (isVisitor && e.RootFolderType == FolderType.Templates) { continue; } if (isVisitor && e.RootFolderType == FolderType.Privacy) { continue; } if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Projects) { // Root Projects folder read-only continue; } if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.SHARE) { // Root Share folder read-only continue; } if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Recent) { // Recent folder read-only continue; } if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Favorites) { // Favorites folder read-only continue; } if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Templates) { // Templates folder read-only continue; } if (isVisitor && e.ProviderEntry) { continue; } if (e.RootFolderType == FolderType.USER && e.RootFolderCreator == userId && !isVisitor) { // user has all right in his folder result.Add(e); continue; } if (e.RootFolderType == FolderType.Privacy && e.RootFolderCreator == userId && !isVisitor) { // user has all right in his privacy folder result.Add(e); continue; } if (DefaultCommonShare == FileShare.Read && action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.COMMON) { // all can read Common folder result.Add(e); continue; } if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.SHARE) { // all can read Share folder result.Add(e); continue; } if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Recent) { // all can read recent folder result.Add(e); continue; } if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Favorites) { // all can read favorites folder result.Add(e); continue; } if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder <T>)e).FolderType == FolderType.Templates) { // all can read templates folder result.Add(e); continue; } if (e.RootFolderType == FolderType.COMMON && FileSecurityCommon.IsAdministrator(userId)) { // administrator in Common has all right result.Add(e); continue; } if (shares == null) { shares = GetShares(entries).Join(subjects, r => r.Subject, s => s, (r, s) => r).ToList(); // shares ordered by level } FileShareRecord ace; if (e.FileEntryType == FileEntryType.File) { ace = shares .OrderBy(r => r, new SubjectComparer(subjects)) .ThenByDescending(r => r.Share, new FileShareRecord.ShareComparer()) .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 <T>)e).FolderID) && r.EntryType == FileEntryType.Folder) .OrderBy(r => r, new SubjectComparer(subjects)) .ThenBy(r => r.Level) .ThenByDescending(r => r.Share, new FileShareRecord.ShareComparer()) .FirstOrDefault(); } } else { ace = shares.Where(r => Equals(r.EntryId, e.ID) && r.EntryType == FileEntryType.Folder) .OrderBy(r => r, new SubjectComparer(subjects)) .ThenBy(r => r.Level) .ThenByDescending(r => r.Share, new FileShareRecord.ShareComparer()) .FirstOrDefault(); } var defaultShare = e.RootFolderType == FolderType.USER ? DefaultMyShare : e.RootFolderType == FolderType.Privacy ? DefaultPrivacyShare : DefaultCommonShare; e.Access = ace != null ? ace.Share : userId == FileConstant.ShareLinkId ? FileShare.Restrict : defaultShare; if (action == FilesSecurityActions.Read && e.Access != FileShare.Restrict) { result.Add(e); } else if (action == FilesSecurityActions.Comment && (e.Access == FileShare.Comment || e.Access == FileShare.Review || e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite)) { result.Add(e); } else if (action == FilesSecurityActions.FillForms && (e.Access == FileShare.FillForms || e.Access == FileShare.Review || e.Access == FileShare.ReadWrite)) { result.Add(e); } else if (action == FilesSecurityActions.Review && (e.Access == FileShare.Review || e.Access == FileShare.ReadWrite)) { result.Add(e); } else if (action == FilesSecurityActions.CustomFilter && (e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite)) { 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); } else if (e.Access != FileShare.Restrict && e.CreateBy == userId && (e.FileEntryType == FileEntryType.File || ((Folder <T>)e).FolderType != FolderType.COMMON)) { 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)) { var folderDao = daoFactory.GetFolderDao <T>(); var filteredEntries = entries.Where(filter).ToList(); var roots = filteredEntries .Select(r => r.RootFolderId) .ToArray(); var rootsFolders = folderDao.GetFolders(roots); var bunches = folderDao.GetBunchObjectIDs(rootsFolders.Select(r => r.ID).ToList()); var findedAdapters = FilesIntegration.GetFileSecurity(bunches); foreach (var e in filteredEntries) { var adapter = findedAdapters[e.RootFolderId.ToString()]; if (adapter == null) { continue; } if (adapter.CanRead(e, userId) && adapter.CanCreate(e, userId) && adapter.CanEdit(e, userId) && adapter.CanDelete(e, userId)) { e.Access = FileShare.None; result.Add(e); } else if (action == FilesSecurityActions.Comment && adapter.CanComment(e, userId)) { e.Access = FileShare.Comment; result.Add(e); } else if (action == FilesSecurityActions.FillForms && adapter.CanFillForms(e, userId)) { e.Access = FileShare.FillForms; result.Add(e); } else if (action == FilesSecurityActions.Review && adapter.CanReview(e, userId)) { e.Access = FileShare.Review; result.Add(e); } else if (action == FilesSecurityActions.CustomFilter && adapter.CanCustomFilterEdit(e, userId)) { e.Access = FileShare.CustomFilter; result.Add(e); } else if (action == FilesSecurityActions.Create && adapter.CanCreate(e, userId)) { e.Access = FileShare.ReadWrite; result.Add(e); } else if (action == FilesSecurityActions.Delete && adapter.CanDelete(e, userId)) { e.Access = FileShare.ReadWrite; result.Add(e); } else if (action == FilesSecurityActions.Read && adapter.CanRead(e, userId)) { if (adapter.CanCreate(e, userId) || adapter.CanDelete(e, userId) || adapter.CanEdit(e, userId)) { e.Access = FileShare.ReadWrite; } else { e.Access = FileShare.Read; } result.Add(e); } else if (action == FilesSecurityActions.Edit && adapter.CanEdit(e, userId)) { e.Access = FileShare.ReadWrite; result.Add(e); } } } // files in trash filter = f => f.RootFolderType == FolderType.TRASH; if ((action == FilesSecurityActions.Read || action == FilesSecurityActions.Delete) && entries.Any(filter)) { var folderDao = daoFactory.GetFolderDao <T>(); var mytrashId = folderDao.GetFolderIDTrash(false, userId); if (!Equals(mytrashId, 0)) { result.AddRange(entries.Where(filter).Where(e => Equals(e.RootFolderId, mytrashId))); } } if (FileSecurityCommon.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); }
private IEnumerable <Guid> WhoCan <T>(FileEntry <T> entry, FilesSecurityActions action) { var shares = GetShares(entry); FileShareRecord defaultShareRecord; switch (entry.RootFolderType) { case FolderType.COMMON: defaultShareRecord = new FileShareRecord { Level = int.MaxValue, EntryId = entry.ID, EntryType = entry.FileEntryType, Share = DefaultCommonShare, Subject = Constants.GroupEveryone.ID, Tenant = TenantManager.GetCurrentTenant().TenantId, Owner = AuthContext.CurrentAccount.ID }; if (!shares.Any()) { if ((defaultShareRecord.Share == FileShare.Read && action == FilesSecurityActions.Read) || (defaultShareRecord.Share == FileShare.ReadWrite)) { return(UserManager.GetUsersByGroup(defaultShareRecord.Subject) .Where(x => x.Status == EmployeeStatus.Active).Select(y => y.ID).Distinct()); } return(Enumerable.Empty <Guid>()); } break; case FolderType.USER: defaultShareRecord = new FileShareRecord { Level = int.MaxValue, EntryId = entry.ID, EntryType = entry.FileEntryType, Share = DefaultMyShare, Subject = entry.RootFolderCreator, Tenant = TenantManager.GetCurrentTenant().TenantId, Owner = entry.RootFolderCreator }; if (!shares.Any()) { return new List <Guid> { entry.RootFolderCreator } } ; break; case FolderType.Privacy: defaultShareRecord = new FileShareRecord { Level = int.MaxValue, EntryId = entry.ID, EntryType = entry.FileEntryType, Share = DefaultPrivacyShare, Subject = entry.RootFolderCreator, Tenant = TenantManager.GetCurrentTenant().TenantId, Owner = entry.RootFolderCreator }; if (!shares.Any()) { return new List <Guid> { entry.RootFolderCreator } } ; break; case FolderType.BUNCH: if (action == FilesSecurityActions.Read) { var folderDao = daoFactory.GetFolderDao <T>(); var root = folderDao.GetFolder(entry.RootFolderId); if (root != null) { var path = folderDao.GetBunchObjectID(root.ID); var adapter = FilesIntegration.GetFileSecurity(path); if (adapter != null) { return(adapter.WhoCanRead(entry)); } } } // TODO: For Projects and other defaultShareRecord = null; break; default: defaultShareRecord = null; break; } if (defaultShareRecord != null) { shares = shares.Concat(new[] { defaultShareRecord }); } return(shares.SelectMany(x => { var groupInfo = UserManager.GetGroupInfo(x.Subject); if (groupInfo.ID != Constants.LostGroupInfo.ID) { return UserManager.GetUsersByGroup(groupInfo.ID) .Where(p => p.Status == EmployeeStatus.Active) .Select(y => y.ID); } return new[] { x.Subject }; }) .Distinct() .Where(x => Can(entry, x, action)) .ToList()); }
private bool Can <T>(FileEntry <T> entry, Guid userId, FilesSecurityActions action) { return(Filter(new[] { entry }, action, userId).Any()); }
private bool Can(FileEntry entry, Guid userId, FilesSecurityActions action, IEnumerable <FileShareRecord> shares = null) { return(Filter(new[] { entry }, action, userId, shares).Any()); }
private IEnumerable <FileEntry> Filter(IEnumerable <FileEntry> entries, FilesSecurityActions action, Guid userId) { if (entries == null || !entries.Any()) { return(Enumerable.Empty <FileEntry>()); } var user = CoreContext.UserManager.GetUsers(userId); var isOutsider = user.IsOutsider(); if (isOutsider && action != FilesSecurityActions.Read) { 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 || f.RootFolderType == FolderType.Projects; var isVisitor = user.IsVisitor(); 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 (isOutsider && (e.RootFolderType == FolderType.USER || e.RootFolderType == FolderType.SHARE || e.RootFolderType == FolderType.TRASH)) { continue; } if (action != FilesSecurityActions.Read && e is Folder && ((Folder)e).FolderType == FolderType.Projects) { // Root Projects folder read-only continue; } if (action != FilesSecurityActions.Read && e is Folder && ((Folder)e).FolderType == FolderType.SHARE) { // Root Share folder read-only continue; } if (isVisitor && e.ProviderEntry) { continue; } if (e.RootFolderType == FolderType.USER && e.RootFolderCreator == userId && !isVisitor) { // 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 => r, new SubjectComparer(subjects)) .ThenByDescending(r => r.Share) .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 => r, new SubjectComparer(subjects)) .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 => r, new SubjectComparer(subjects)) .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.Restrict) { result.Add(e); } else if (action == FilesSecurityActions.Review && (e.Access == FileShare.Review || e.Access == FileShare.ReadWrite)) { 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); } else if (e.Access != FileShare.Restrict && e.CreateBy == userId && (e is File || ((Folder)e).FolderType != FolderType.COMMON)) { 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 folderDao = 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 = folderDao.GetFolder(e.RootFolderId); if (root != null) { var path = folderDao.GetBunchObjectID(root.ID); adapter = FilesIntegration.GetFileSecurity(path); } findedAdapters[e.RootFolderId] = adapter; } adapter = findedAdapters[e.RootFolderId]; if (adapter == null) { continue; } if (adapter.CanRead(e, userId) && adapter.CanCreate(e, userId) && adapter.CanEdit(e, userId) && adapter.CanDelete(e, userId)) { e.Access = FileShare.None; result.Add(e); } else if (action == FilesSecurityActions.Create && adapter.CanCreate(e, userId)) { e.Access = FileShare.ReadWrite; result.Add(e); } else if (action == FilesSecurityActions.Delete && adapter.CanDelete(e, userId)) { e.Access = FileShare.ReadWrite; result.Add(e); } else if (action == FilesSecurityActions.Read && adapter.CanRead(e, userId)) { if (adapter.CanCreate(e, userId) || adapter.CanDelete(e, userId) || adapter.CanEdit(e, userId)) { e.Access = FileShare.ReadWrite; } else { e.Access = FileShare.Read; } result.Add(e); } else if (action == FilesSecurityActions.Edit && adapter.CanEdit(e, userId)) { e.Access = FileShare.ReadWrite; result.Add(e); } } } } // files in trash filter = f => f.RootFolderType == FolderType.TRASH; if (entries.Any(filter)) { using (var folderDao = daoFactory.GetFolderDao()) { var mytrashId = folderDao.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); }
private IEnumerable <Guid> WhoCan(FileEntry fileEntry, FilesSecurityActions action) { var shares = GetShares(fileEntry); FileShareRecord defaultShareRecord; switch (fileEntry.RootFolderType) { case FolderType.COMMON: defaultShareRecord = new FileShareRecord { Level = int.MaxValue, EntryId = fileEntry.ID, EntryType = fileEntry is File ? FileEntryType.File : FileEntryType.Folder, Share = DefaultCommonShare, Subject = Constants.GroupEveryone.ID, Tenant = TenantProvider.CurrentTenantID, Owner = SecurityContext.CurrentAccount.ID }; if (!shares.Any()) { if ((defaultShareRecord.Share == FileShare.Read && action == FilesSecurityActions.Read) || (defaultShareRecord.Share == FileShare.ReadWrite)) { return(CoreContext.UserManager.GetUsersByGroup(defaultShareRecord.Subject) .Where(x => x.Status == EmployeeStatus.Active).Select(y => y.ID).Distinct()); } return(Enumerable.Empty <Guid>()); } break; case FolderType.USER: defaultShareRecord = new FileShareRecord { Level = int.MaxValue, EntryId = fileEntry.ID, EntryType = fileEntry is File ? FileEntryType.File : FileEntryType.Folder, Share = DefaultMyShare, Subject = fileEntry.RootFolderCreator, Tenant = TenantProvider.CurrentTenantID, Owner = fileEntry.RootFolderCreator }; if (!shares.Any()) { return new List <Guid> { fileEntry.RootFolderCreator } } ; break; default: defaultShareRecord = null; break; } // TODO: For Projects and other if (defaultShareRecord != null) { shares = shares.Concat(new[] { defaultShareRecord }); } return(shares.SelectMany(x => { var groupInfo = CoreContext.GroupManager.GetGroupInfo(x.Subject); if (groupInfo.ID != Constants.LostGroupInfo.ID) { return CoreContext.UserManager.GetUsersByGroup(groupInfo.ID) .Where(p => p.Status == EmployeeStatus.Active) .Select(y => y.ID); } return new[] { x.Subject }; }) .Distinct() .Where(x => Can(fileEntry, x, action))); }
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; }
private bool Can(FileEntry entry, Guid userId, FilesSecurityActions action) { return Filter(new[] {entry}, action, userId).Any(); }