Beispiel #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));
        }
Beispiel #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);
 }
Beispiel #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);
 }
Beispiel #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);
        }
Beispiel #5
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);
        }