Example #1
0
        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());
        }
Example #2
0
        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);
        }
Example #3
0
        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());
        }
Example #4
0
 private bool Can <T>(FileEntry <T> entry, Guid userId, FilesSecurityActions action)
 {
     return(Filter(new[] { entry }, action, userId).Any());
 }
Example #5
0
 private bool Can(FileEntry entry, Guid userId, FilesSecurityActions action, IEnumerable <FileShareRecord> shares = null)
 {
     return(Filter(new[] { entry }, action, userId, shares).Any());
 }
Example #6
0
        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);
        }
Example #7
0
        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)));
        }
Example #8
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;
        }
Example #9
0
 private bool Can(FileEntry entry, Guid userId, FilesSecurityActions action)
 {
     return Filter(new[] {entry}, action, userId).Any();
 }