Beispiel #1
0
 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>();
 }
Beispiel #2
0
        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);
        }