예제 #1
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);
        }
예제 #2
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);
        }