Esempio n. 1
0
        public IEnumerable <AdamItem> Folder(int appId, string contentType, Guid guid, string field, string subfolder, string newFolder, bool usePortalRoot)
        {
            Log.Add($"get folders for a:{appId}, i:{guid}, field:{field}, subfld:{subfolder}, new:{newFolder}, useRoot:{usePortalRoot}");
            var state = new AdamSecureState(BlockBuilder, appId, contentType, field, guid, usePortalRoot, Log);

            if (state.UserIsRestricted && !state.FieldPermissionOk(GrantSets.ReadSomething))
            {
                return(null);
            }

            // get root and at the same time auto-create the core folder in case it's missing (important)
            var folder = state.ContainerContext.Folder();

            // try to see if we can get into the subfolder - will throw error if missing
            if (!string.IsNullOrEmpty(subfolder))
            {
                folder = state.ContainerContext.Folder(subfolder, false);
            }

            // start with a security check...
            var dnnFolder = FolderManager.Instance.GetFolder(folder.Id);

            // validate that dnn user have write permissions for folder in case dnn file system is used (usePortalRoot)
            if (usePortalRoot && !SecurityChecks.CanEdit(dnnFolder))
            {
                throw Http.PermissionDenied("can't create new folder - permission denied");
            }

            var newFolderPath = string.IsNullOrEmpty(subfolder) ? newFolder : Path.Combine(subfolder, newFolder).Replace("\\", "/");

            // now access the subfolder, creating it if missing (which is what we want
            state.ContainerContext.Folder(newFolderPath, true);

            return(Items(appId, contentType, guid, field, subfolder, usePortalRoot));
        }
Esempio n. 2
0
 internal AdamItem(IFolderInfo original, bool usePortalRoot, AdamSecureState state)
 {
     IsFolder  = true;
     Id        = original.FolderID;
     ParentId  = original.ParentID;
     Path      = original.DisplayPath;
     Name      = original.DisplayName;
     Size      = 0;
     Type      = "folder";
     Created   = original.CreatedOnDate;
     Modified  = original.LastModifiedOnDate;
     AllowEdit = usePortalRoot ? SecurityChecks.CanEdit(original) : !state.UserIsRestricted || state.FieldPermissionOk(GrantSets.WriteSomething);
 }
Esempio n. 3
0
 internal AdamItem(IFileInfo original, bool usePortalRoot, AdamSecureState state)
 {
     IsFolder  = false;
     Id        = original.FileId;
     ParentId  = original.FolderId;
     Path      = original.RelativePath;
     Name      = original.FileName;
     Size      = original.Size;
     Type      = "unknown"; // will be set from the outside
     Created   = original.CreatedOnDate;
     Modified  = original.LastModifiedOnDate;
     AllowEdit = usePortalRoot ? SecurityChecks.CanEdit(original) : !state.UserIsRestricted || state.FieldPermissionOk(GrantSets.WriteSomething);
 }
Esempio n. 4
0
        public bool Rename(int appId, string contentType, Guid guid, string field, string subfolder, bool isFolder, int id, string newName, bool usePortalRoot)
        {
            Log.Add($"rename a:{appId}, i:{guid}, field:{field}, subf:{subfolder}, isfld:{isFolder}, new:{newName}, useRoot:{usePortalRoot}");

            var state = new AdamSecureState(BlockBuilder, appId, contentType, field, guid, usePortalRoot, Log);

            if (!state.UserIsPermittedOnField(GrantSets.WriteSomething, out var exp))
            {
                throw exp;
            }

            // check that if the user should only see drafts, he doesn't see items of published data
            if (!state.UserIsNotRestrictedOrItemIsDraft(guid, out var permissionException))
            {
                throw permissionException;
            }

            // try to see if we can get into the subfolder - will throw error if missing
            var current = state.ContainerContext.Folder(subfolder, false);

            if (isFolder)
            {
                var folderManager = FolderManager.Instance;
                var fld           = folderManager.GetFolder(id);

                // validate that dnn user have write permissions for folder in case dnn file system is used (usePortalRoot)
                if (usePortalRoot && !SecurityChecks.CanEdit(fld))
                {
                    throw Http.PermissionDenied("can't rename folder - permission denied");
                }

                if (!state.SuperUserOrAccessingItemFolder(fld.PhysicalPath, out exp))
                {
                    throw exp;
                }

                if (fld.ParentID != current.Id)
                {
                    throw Http.BadRequest("can't rename folder - not found in folder");
                }
                folderManager.RenameFolder(fld, newName);
            }
            else
            {
                var fileManager = FileManager.Instance;
                var file        = fileManager.GetFile(id);

                // validate that dnn user have write permissions for folder where is file in case dnn file system is used (usePortalRoot)
                if (usePortalRoot && !SecurityChecks.CanEdit(file))
                {
                    throw Http.PermissionDenied("can't rename file - permission denied");
                }

                if (!state.SuperUserOrAccessingItemFolder(file.PhysicalPath, out exp))
                {
                    throw exp;
                }

                if (file.FolderId != current.Id)
                {
                    throw Http.BadRequest("can't rename file - not found in folder");
                }

                // never allow to change the extension
                if (file.Extension != newName.Split('.').Last())
                {
                    newName += "." + file.Extension;
                }
                fileManager.RenameFile(file, newName);
            }

            Log.Add("rename complete");
            return(true);
        }
Esempio n. 5
0
        public IEnumerable <AdamItem> Items(int appId, string contentType, Guid guid, string field, string subfolder, bool usePortalRoot = false)
        {
            var wrapLog = Log.Call <IEnumerable <AdamItem> >(parameters: $"adam items a:{appId}, i:{guid}, field:{field}, subfolder:{subfolder}, useRoot:{usePortalRoot}");
            var state   = new AdamSecureState(BlockBuilder, appId, contentType, field, guid, usePortalRoot, Log);


            Log.Add("starting permissions checks");
            if (state.UserIsRestricted && !state.FieldPermissionOk(GrantSets.ReadSomething))
            {
                return(wrapLog("user is restricted, and doesn't have permissions on field - return null", null));
            }

            // check that if the user should only see drafts, he doesn't see items of published data
            if (!state.UserIsNotRestrictedOrItemIsDraft(guid, out var _))
            {
                return(wrapLog("user is restricted (no read-published rights) and item is published - return null", null));
            }

            Log.Add("first permission checks passed");


            // get root and at the same time auto-create the core folder in case it's missing (important)
            state.ContainerContext.Folder();

            // try to see if we can get into the subfolder - will throw error if missing
            var currentAdam   = state.ContainerContext.Folder(subfolder, false);
            var folderManager = FolderManager.Instance;
            var currentDnn    = folderManager.GetFolder(currentAdam.Id);

            // ensure that it's super user, or the folder is really part of this item
            if (!state.SuperUserOrAccessingItemFolder(currentDnn.PhysicalPath, out var exp))
            {
                Log.Add("user is not super-user and folder doesn't seem to be an ADAM folder of this item - will throw");
                throw exp;
            }

            var subfolders = folderManager.GetFolders(currentDnn);
            var files      = folderManager.GetFiles(currentDnn);

            var all = new List <AdamItem>();

            // currentFolder is needed to get allowEdit for Adam root folder
            var currentFolder = new AdamItem(currentDnn, usePortalRoot, state)
            {
                Name       = ".",
                MetadataId = Metadata.GetMetadataId(state.AdamAppContext.AppRuntime, currentDnn.FolderID, true)
            };

            all.Insert(0, currentFolder);

            var adamFolders = subfolders.Where(s => s.FolderID != currentDnn.FolderID)
                              .Select(f => new AdamItem(f, usePortalRoot, state)
            {
                MetadataId = Metadata.GetMetadataId(state.AdamAppContext.AppRuntime, f.FolderID, true)
            })
                              .ToList();

            all.AddRange(adamFolders);

            var adamFiles = files
                            .Select(f => new AdamItem(f, usePortalRoot, state)
            {
                MetadataId = Metadata.GetMetadataId(state.AdamAppContext.AppRuntime, f.FileId, false),
                Type       = Classification.TypeName(f.Extension)
            })
                            .ToList();

            all.AddRange(adamFiles);

            Log.Add($"items complete - will return fld⋮{adamFolders.Count}, files⋮{adamFiles.Count} tot⋮{all.Count}");
            return(all);
        }
Esempio n. 6
0
        public IFile UploadOne(Stream stream, string originalFileName, string contentType, Guid guid, string field, string subFolder, bool usePortalRoot, bool skipFieldAndContentTypePermissionCheck)
        {
            Log.Add($"upload one a:{_appId}, i:{guid}, field:{field}, subfold:{subFolder}, useRoot:{usePortalRoot}");

            var state = new AdamSecureState(BlockBuilder, _appId, contentType, field, guid, usePortalRoot, Log);
            HttpResponseException exp;

            if (!skipFieldAndContentTypePermissionCheck)
            {
                if (!state.UserIsPermittedOnField(GrantSets.WriteSomething, out exp))
                {
                    throw exp;
                }

                // check that if the user should only see drafts, he doesn't see items of published data
                if (!state.UserIsNotRestrictedOrItemIsDraft(guid, out var permissionException))
                {
                    throw permissionException;
                }
            }

            var folder = state.ContainerContext.Folder();

            if (!string.IsNullOrEmpty(subFolder))
            {
                folder = state.ContainerContext.Folder(subFolder, false);
            }

            // start with a security check...
            var dnnFolder = FolderManager.Instance.GetFolder(folder.Id);

            // validate that dnn user have write permissions for folder in case dnn file system is used (usePortalRoot)
            if (usePortalRoot && !SecurityChecks.CanEdit(dnnFolder))
            {
                throw Http.PermissionDenied("can't upload - permission denied");
            }

            // we only upload into valid adam if that's the scenario
            if (!state.SuperUserOrAccessingItemFolder(dnnFolder.PhysicalPath, out exp))
            {
                throw exp;
            }

            #region check content-type extensions...

            // Check file size and extension
            var fileName = String.Copy(originalFileName);
            if (!state.ExtensionIsOk(fileName, out exp))
            {
                throw exp;
            }

            // check metadata of the FieldDef to see if still allowed extension
            var additionalFilter = state.Attribute.Metadata.GetBestValue <string>("FileFilter");
            if (!string.IsNullOrWhiteSpace(additionalFilter) &&
                !state.CustomFileFilterOk(additionalFilter, originalFileName))
            {
                throw Http.NotAllowedFileType(fileName, "field has custom file-filter, which doesn't match");
            }

            // note 2018-04-20 2dm: can't do this for wysiwyg, as it doesn't have a setting for allowed file-uploads

            #endregion

            if (stream.Length > 1024 * MaxFileSizeKb)
            {
                throw new Exception($"file too large - more than {MaxFileSizeKb}Kb");
            }

            // remove forbidden / troubling file name characters
            fileName = fileName
                       .Replace("+", "plus")
                       .Replace("%", "per")
                       .Replace("#", "hash");

            if (fileName != originalFileName)
            {
                Log.Add($"cleaned file name from'{originalFileName}' to '{fileName}'");
            }

            // Make sure the image does not exist yet, cycle through numbers (change file name)
            fileName = RenameFileToNotOverwriteExisting(fileName, dnnFolder);

            // Everything is ok, add file to DNN
            var dnnFile = FileManager.Instance.AddFile(dnnFolder, Path.GetFileName(fileName),
                                                       stream);

            var adamcontext = new AdamAppContext(BlockBuilder.Block.Tenant, state.App, BlockBuilder, 10, Log);
            var eavFile     = new File(adamcontext)
            {
                Created   = dnnFile.CreatedOnDate,
                Extension = dnnFile.Extension,
                FullName  = dnnFile.FileName,
                Folder    = dnnFile.Folder,
                FolderId  = dnnFile.FolderId,
                Id        = dnnFile.FileId,
                Modified  = dnnFile.LastModificationTime
            };

            return(eavFile);
        }