Exemplo n.º 1
0
        public async Task <HttpResponseMessage> PostAddFile()
        {
            if (Request.Content.IsMimeMultipartContent() == false)
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var root = IOHelper.MapPath(SystemDirectories.TempFileUploads);

            //ensure it exists
            Directory.CreateDirectory(root);
            var provider = new MultipartFormDataStreamProvider(root);

            var result = await Request.Content.ReadAsMultipartAsync(provider);

            //must have a file
            if (result.FileData.Count == 0)
            {
                return(Request.CreateResponse(HttpStatusCode.NotFound));
            }

            //get the string json from the request
            string currentFolderId = result.FormData["currentFolder"];
            int    parentId        = GetParentIdAsInt(currentFolderId, validatePermissions: true);

            var tempFiles    = new PostedFiles();
            var mediaService = Services.MediaService;

            //in case we pass a path with a folder in it, we will create it and upload media to it.
            if (result.FormData.ContainsKey("path"))
            {
                var folders = result.FormData["path"].Split(Constants.CharArrays.ForwardSlash);

                for (int i = 0; i < folders.Length - 1; i++)
                {
                    var    folderName = folders[i];
                    IMedia folderMediaItem;

                    //if uploading directly to media root and not a subfolder
                    if (parentId == -1)
                    {
                        //look for matching folder
                        folderMediaItem =
                            mediaService.GetRootMedia().FirstOrDefault(x => x.Name == folderName && x.ContentType.Alias == Constants.Conventions.MediaTypes.Folder);
                        if (folderMediaItem == null)
                        {
                            //if null, create a folder
                            folderMediaItem = mediaService.CreateMedia(folderName, -1, Constants.Conventions.MediaTypes.Folder);
                            mediaService.Save(folderMediaItem);
                        }
                    }
                    else
                    {
                        //get current parent
                        var mediaRoot = mediaService.GetById(parentId);

                        //if the media root is null, something went wrong, we'll abort
                        if (mediaRoot == null)
                        {
                            return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError,
                                                               "The folder: " + folderName + " could not be used for storing images, its ID: " + parentId +
                                                               " returned null"));
                        }

                        //look for matching folder
                        folderMediaItem = FindInChildren(mediaRoot.Id, folderName, Constants.Conventions.MediaTypes.Folder);

                        if (folderMediaItem == null)
                        {
                            //if null, create a folder
                            folderMediaItem = mediaService.CreateMedia(folderName, mediaRoot, Constants.Conventions.MediaTypes.Folder);
                            mediaService.Save(folderMediaItem);
                        }
                    }
                    //set the media root to the folder id so uploaded files will end there.
                    parentId = folderMediaItem.Id;
                }
            }

            //get the files
            foreach (var file in result.FileData)
            {
                var fileName     = file.Headers.ContentDisposition.FileName.Trim(Constants.CharArrays.DoubleQuote).TrimEnd();
                var safeFileName = fileName.ToSafeFileName();
                var ext          = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();

                if (Current.Configs.Settings().Content.IsFileAllowedForUpload(ext))
                {
                    var mediaType = Constants.Conventions.MediaTypes.File;

                    if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.AutoSelect)
                    {
                        if (Current.Configs.Settings().Content.ImageFileTypes.Contains(ext))
                        {
                            mediaType = Constants.Conventions.MediaTypes.Image;
                        }
                    }
                    else
                    {
                        mediaType = result.FormData["contentTypeAlias"];
                    }

                    var mediaItemName = fileName.ToFriendlyName();

                    var f = mediaService.CreateMedia(mediaItemName, parentId, mediaType, Security.CurrentUser.Id);

                    var fileInfo = new FileInfo(file.LocalFileName);
                    var fs       = fileInfo.OpenReadWithRetry();
                    if (fs == null)
                    {
                        throw new InvalidOperationException("Could not acquire file stream");
                    }
                    using (fs)
                    {
                        f.SetValue(Services.ContentTypeBaseServices, Constants.Conventions.Media.File, fileName, fs);
                    }

                    var saveResult = mediaService.Save(f, Security.CurrentUser.Id);
                    if (saveResult == false)
                    {
                        AddCancelMessage(tempFiles,
                                         message: Services.TextService.Localize("speechBubbles/operationCancelledText") + " -- " + mediaItemName);
                    }
                    else
                    {
                        tempFiles.UploadedFiles.Add(new ContentPropertyFile
                        {
                            FileName      = fileName,
                            PropertyAlias = Constants.Conventions.Media.File,
                            TempFilePath  = file.LocalFileName
                        });
                    }
                }
                else
                {
                    tempFiles.Notifications.Add(new Notification(
                                                    Services.TextService.Localize("speechBubbles/operationFailedHeader"),
                                                    Services.TextService.Localize("media/disallowedFileType"),
                                                    NotificationStyle.Warning));
                }
            }

            //Different response if this is a 'blueimp' request
            if (Request.GetQueryNameValuePairs().Any(x => x.Key == "origin"))
            {
                var origin = Request.GetQueryNameValuePairs().First(x => x.Key == "origin");
                if (origin.Value == "blueimp")
                {
                    return(Request.CreateResponse(HttpStatusCode.OK,
                                                  tempFiles,
                                                  //Don't output the angular xsrf stuff, blue imp doesn't like that
                                                  new JsonMediaTypeFormatter()));
                }
            }

            return(Request.CreateResponse(HttpStatusCode.OK, tempFiles));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Used to submit a media file
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// We cannot validate this request with attributes (nicely) due to the nature of the multi-part for data.
        /// </remarks>
        public async Task <IActionResult> PostAddFile([FromForm] string path, [FromForm] string currentFolder, [FromForm] string contentTypeAlias, List <IFormFile> file)
        {
            var root = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempFileUploads);

            //ensure it exists
            Directory.CreateDirectory(root);

            //must have a file
            if (file.Count == 0)
            {
                return(NotFound());
            }

            //get the string json from the request
            var parentIdResult = await GetParentIdAsIntAsync(currentFolder, validatePermissions : true);

            if (!(parentIdResult.Result is null))
            {
                return(parentIdResult.Result);
            }

            var parentId = parentIdResult.Value;

            if (!parentId.HasValue)
            {
                return(NotFound("The passed id doesn't exist"));
            }

            var tempFiles = new PostedFiles();

            //in case we pass a path with a folder in it, we will create it and upload media to it.
            if (!string.IsNullOrEmpty(path))
            {
                if (!IsFolderCreationAllowedHere(parentId.Value))
                {
                    AddCancelMessage(tempFiles, _localizedTextService.Localize("speechBubbles", "folderUploadNotAllowed"));
                    return(Ok(tempFiles));
                }

                var folders = path.Split(Constants.CharArrays.ForwardSlash);

                for (int i = 0; i < folders.Length - 1; i++)
                {
                    var    folderName = folders[i];
                    IMedia folderMediaItem;

                    //if uploading directly to media root and not a subfolder
                    if (parentId == Constants.System.Root)
                    {
                        //look for matching folder
                        folderMediaItem =
                            _mediaService.GetRootMedia().FirstOrDefault(x => x.Name == folderName && x.ContentType.Alias == Constants.Conventions.MediaTypes.Folder);
                        if (folderMediaItem == null)
                        {
                            //if null, create a folder
                            folderMediaItem = _mediaService.CreateMedia(folderName, -1, Constants.Conventions.MediaTypes.Folder);
                            _mediaService.Save(folderMediaItem);
                        }
                    }
                    else
                    {
                        //get current parent
                        var mediaRoot = _mediaService.GetById(parentId.Value);

                        //if the media root is null, something went wrong, we'll abort
                        if (mediaRoot == null)
                        {
                            return(Problem(
                                       "The folder: " + folderName + " could not be used for storing images, its ID: " + parentId +
                                       " returned null"));
                        }

                        //look for matching folder
                        folderMediaItem = FindInChildren(mediaRoot.Id, folderName, Constants.Conventions.MediaTypes.Folder);

                        if (folderMediaItem == null)
                        {
                            //if null, create a folder
                            folderMediaItem = _mediaService.CreateMedia(folderName, mediaRoot, Constants.Conventions.MediaTypes.Folder);
                            _mediaService.Save(folderMediaItem);
                        }
                    }

                    //set the media root to the folder id so uploaded files will end there.
                    parentId = folderMediaItem.Id;
                }
            }

            var mediaTypeAlias      = string.Empty;
            var allMediaTypes       = _mediaTypeService.GetAll().ToList();
            var allowedContentTypes = new HashSet <IMediaType>();

            if (parentId != Constants.System.Root)
            {
                var mediaFolderItem = _mediaService.GetById(parentId.Value);
                var mediaFolderType = allMediaTypes.FirstOrDefault(x => x.Alias == mediaFolderItem.ContentType.Alias);

                if (mediaFolderType != null)
                {
                    IMediaType mediaTypeItem = null;

                    foreach (ContentTypeSort allowedContentType in mediaFolderType.AllowedContentTypes)
                    {
                        IMediaType checkMediaTypeItem = allMediaTypes.FirstOrDefault(x => x.Id == allowedContentType.Id.Value);
                        allowedContentTypes.Add(checkMediaTypeItem);

                        var fileProperty = checkMediaTypeItem?.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == Constants.Conventions.Media.File);
                        if (fileProperty != null)
                        {
                            mediaTypeItem = checkMediaTypeItem;
                        }
                    }

                    //Only set the permission-based mediaType if we only allow 1 specific file under this parent.
                    if (allowedContentTypes.Count == 1 && mediaTypeItem != null)
                    {
                        mediaTypeAlias = mediaTypeItem.Alias;
                    }
                }
            }
            else
            {
                var typesAllowedAtRoot = allMediaTypes.Where(x => x.AllowedAsRoot).ToList();
                allowedContentTypes.UnionWith(typesAllowedAtRoot);
            }

            //get the files
            foreach (var formFile in file)
            {
                var fileName     = formFile.FileName.Trim(Constants.CharArrays.DoubleQuote).TrimEnd();
                var safeFileName = fileName.ToSafeFileName(ShortStringHelper);
                var ext          = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();

                if (!_contentSettings.IsFileAllowedForUpload(ext))
                {
                    tempFiles.Notifications.Add(new BackOfficeNotification(
                                                    _localizedTextService.Localize("speechBubbles", "operationFailedHeader"),
                                                    _localizedTextService.Localize("media", "disallowedFileType"),
                                                    NotificationStyle.Warning));
                    continue;
                }

                if (string.IsNullOrEmpty(mediaTypeAlias))
                {
                    mediaTypeAlias = Constants.Conventions.MediaTypes.File;

                    if (contentTypeAlias == Constants.Conventions.MediaTypes.AutoSelect)
                    {
                        // Look up MediaTypes
                        foreach (var mediaTypeItem in allMediaTypes)
                        {
                            var fileProperty = mediaTypeItem.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == Constants.Conventions.Media.File);
                            if (fileProperty == null)
                            {
                                continue;
                            }

                            var dataTypeKey = fileProperty.DataTypeKey;
                            var dataType    = _dataTypeService.GetDataType(dataTypeKey);

                            if (dataType == null || dataType.Configuration is not IFileExtensionsConfig fileExtensionsConfig)
                            {
                                continue;
                            }

                            var fileExtensions = fileExtensionsConfig.FileExtensions;
                            if (fileExtensions == null || fileExtensions.All(x => x.Value != ext))
                            {
                                continue;
                            }

                            mediaTypeAlias = mediaTypeItem.Alias;
                            break;
                        }

                        // If media type is still File then let's check if it's an image.
                        if (mediaTypeAlias == Constants.Conventions.MediaTypes.File && _imageUrlGenerator.SupportedImageFileTypes.Contains(ext))
                        {
                            mediaTypeAlias = Constants.Conventions.MediaTypes.Image;
                        }
                    }
                    else
                    {
                        mediaTypeAlias = contentTypeAlias;
                    }
                }

                if (allowedContentTypes.Any(x => x.Alias == mediaTypeAlias) == false)
                {
                    tempFiles.Notifications.Add(new BackOfficeNotification(
                                                    _localizedTextService.Localize("speechBubbles", "operationFailedHeader"),
                                                    _localizedTextService.Localize("media", "disallowedMediaType", new[] { mediaTypeAlias }),
                                                    NotificationStyle.Warning));
                    continue;
                }

                var mediaItemName = fileName.ToFriendlyName();

                var createdMediaItem = _mediaService.CreateMedia(mediaItemName, parentId.Value, mediaTypeAlias, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);

                await using (var stream = formFile.OpenReadStream())
                {
                    createdMediaItem.SetValue(_mediaFileManager, _mediaUrlGenerators, _shortStringHelper, _contentTypeBaseServiceProvider, Constants.Conventions.Media.File, fileName, stream);
                }

                var saveResult = _mediaService.Save(createdMediaItem, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
                if (saveResult == false)
                {
                    AddCancelMessage(tempFiles, _localizedTextService.Localize("speechBubbles", "operationCancelledText") + " -- " + mediaItemName);
                }
            }

            //Different response if this is a 'blueimp' request
            if (HttpContext.Request.Query.Any(x => x.Key == "origin"))
            {
                var origin = HttpContext.Request.Query.First(x => x.Key == "origin");
                if (origin.Value == "blueimp")
                {
                    return(new JsonResult(tempFiles)); //Don't output the angular xsrf stuff, blue imp doesn't like that
                }
            }

            return(Ok(tempFiles));
        }
Exemplo n.º 3
0
        internal static async Task <HttpResponseMessage> PostSetAvatarInternal(HttpRequestMessage request, IUserService userService, IAppCache cache, int id)
        {
            if (request.Content.IsMimeMultipartContent() == false)
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var root = IOHelper.MapPath(SystemDirectories.TempFileUploads);

            //ensure it exists
            Directory.CreateDirectory(root);
            var provider = new MultipartFormDataStreamProvider(root);

            var result = await request.Content.ReadAsMultipartAsync(provider);

            //must have a file
            if (result.FileData.Count == 0)
            {
                return(request.CreateResponse(HttpStatusCode.NotFound));
            }

            var user = userService.GetUserById(id);

            if (user == null)
            {
                return(request.CreateResponse(HttpStatusCode.NotFound));
            }

            var tempFiles = new PostedFiles();

            if (result.FileData.Count > 1)
            {
                return(request.CreateValidationErrorResponse("The request was not formatted correctly, only one file can be attached to the request"));
            }

            //get the file info
            var file         = result.FileData[0];
            var fileName     = file.Headers.ContentDisposition.FileName.Trim(Constants.CharArrays.DoubleQuote).TrimEnd();
            var safeFileName = fileName.ToSafeFileName();
            var ext          = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();

            if (Current.Configs.Settings().Content.DisallowedUploadFiles.Contains(ext) == false)
            {
                //generate a path of known data, we don't want this path to be guessable
                user.Avatar = "UserAvatars/" + (user.Id + safeFileName).GenerateHash <SHA1>() + "." + ext;

                using (var fs = System.IO.File.OpenRead(file.LocalFileName))
                {
                    Current.MediaFileSystem.AddFile(user.Avatar, fs, true);
                }

                userService.Save(user);

                //track the temp file so the cleanup filter removes it
                tempFiles.UploadedFiles.Add(new ContentPropertyFile
                {
                    TempFilePath = file.LocalFileName
                });
            }

            return(request.CreateResponse(HttpStatusCode.OK, user.GetUserAvatarUrls(cache)));
        }
Exemplo n.º 4
0
        public async Task <HttpResponseMessage> PostAddFile()
        {
            if (Request.Content.IsMimeMultipartContent() == false)
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var root = IOHelper.MapPath("~/App_Data/TEMP/FileUploads");

            //ensure it exists
            Directory.CreateDirectory(root);
            var provider = new MultipartFormDataStreamProvider(root);

            var result = await Request.Content.ReadAsMultipartAsync(provider);

            //must have a file
            if (result.FileData.Count == 0)
            {
                return(Request.CreateResponse(HttpStatusCode.NotFound));
            }

            //get the string json from the request
            int    parentId; bool entityFound; GuidUdi parentUdi;
            string currentFolderId = result.FormData["currentFolder"];

            // test for udi
            if (GuidUdi.TryParse(currentFolderId, out parentUdi))
            {
                currentFolderId = parentUdi.Guid.ToString();
            }

            if (int.TryParse(currentFolderId, out parentId) == false)
            {
                // if a guid then try to look up the entity
                Guid idGuid;
                if (Guid.TryParse(currentFolderId, out idGuid))
                {
                    var entity = Services.EntityService.GetByKey(idGuid);
                    if (entity != null)
                    {
                        entityFound = true;
                        parentId    = entity.Id;
                    }
                    else
                    {
                        throw new EntityNotFoundException(currentFolderId, "The passed id doesn't exist");
                    }
                }
                else
                {
                    return(Request.CreateValidationErrorResponse("The request was not formatted correctly, the currentFolder is not an integer or Guid"));
                }

                if (entityFound == false)
                {
                    return(Request.CreateValidationErrorResponse("The request was not formatted correctly, the currentFolder is not an integer or Guid"));
                }
            }


            //ensure the user has access to this folder by parent id!
            if (CheckPermissions(
                    new Dictionary <string, object>(),
                    Security.CurrentUser,
                    Services.MediaService, parentId) == false)
            {
                return(Request.CreateResponse(
                           HttpStatusCode.Forbidden,
                           new SimpleNotificationModel(new Notification(
                                                           Services.TextService.Localize("speechBubbles/operationFailedHeader"),
                                                           Services.TextService.Localize("speechBubbles/invalidUserPermissionsText"),
                                                           SpeechBubbleIcon.Warning))));
            }

            var tempFiles    = new PostedFiles();
            var mediaService = ApplicationContext.Services.MediaService;


            //in case we pass a path with a folder in it, we will create it and upload media to it.
            if (result.FormData.ContainsKey("path"))
            {
                var folders = result.FormData["path"].Split('/');

                for (int i = 0; i < folders.Length - 1; i++)
                {
                    var    folderName = folders[i];
                    IMedia folderMediaItem;

                    //if uploading directly to media root and not a subfolder
                    if (parentId == -1)
                    {
                        //look for matching folder
                        folderMediaItem =
                            mediaService.GetRootMedia().FirstOrDefault(x => x.Name == folderName && x.ContentType.Alias == Constants.Conventions.MediaTypes.Folder);
                        if (folderMediaItem == null)
                        {
                            //if null, create a folder
                            folderMediaItem = mediaService.CreateMedia(folderName, -1, Constants.Conventions.MediaTypes.Folder);
                            mediaService.Save(folderMediaItem);
                        }
                    }
                    else
                    {
                        //get current parent
                        var mediaRoot = mediaService.GetById(parentId);

                        //if the media root is null, something went wrong, we'll abort
                        if (mediaRoot == null)
                        {
                            return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError,
                                                               "The folder: " + folderName + " could not be used for storing images, its ID: " + parentId +
                                                               " returned null"));
                        }

                        //look for matching folder
                        folderMediaItem = mediaRoot.Children().FirstOrDefault(x => x.Name == folderName && x.ContentType.Alias == Constants.Conventions.MediaTypes.Folder);
                        if (folderMediaItem == null)
                        {
                            //if null, create a folder
                            folderMediaItem = mediaService.CreateMedia(folderName, mediaRoot, Constants.Conventions.MediaTypes.Folder);
                            mediaService.Save(folderMediaItem);
                        }
                    }
                    //set the media root to the folder id so uploaded files will end there.
                    parentId = folderMediaItem.Id;
                }
            }

            //get the files
            foreach (var file in result.FileData)
            {
                var fileName     = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' }).TrimEnd();
                var safeFileName = fileName.ToSafeFileName();
                var ext          = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();

                if (UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(ext))
                {
                    var mediaType = Constants.Conventions.MediaTypes.File;

                    if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.AutoSelect)
                    {
                        if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext))
                        {
                            mediaType = Constants.Conventions.MediaTypes.Image;
                        }
                    }
                    else
                    {
                        mediaType = result.FormData["contentTypeAlias"];
                    }

                    //TODO: make the media item name "nice" since file names could be pretty ugly, we have
                    // string extensions to do much of this but we'll need:
                    // * Pascalcase the name (use string extensions)
                    // * strip the file extension
                    // * underscores to spaces
                    // * probably remove 'ugly' characters - let's discuss
                    // All of this logic should exist in a string extensions method and be unit tested
                    // http://issues.umbraco.org/issue/U4-5572
                    var mediaItemName = fileName;

                    var f = mediaService.CreateMedia(mediaItemName, parentId, mediaType, Security.CurrentUser.Id);

                    var fileInfo = new FileInfo(file.LocalFileName);
                    var fs       = fileInfo.OpenReadWithRetry();
                    if (fs == null)
                    {
                        throw new InvalidOperationException("Could not acquire file stream");
                    }
                    using (fs)
                    {
                        f.SetValue(Constants.Conventions.Media.File, fileName, fs);
                    }

                    var saveResult = mediaService.WithResult().Save(f, Security.CurrentUser.Id);
                    if (saveResult == false)
                    {
                        AddCancelMessage(tempFiles,
                                         message: Services.TextService.Localize("speechBubbles/operationCancelledText") + " -- " + mediaItemName,
                                         localizeMessage: false);
                    }
                    else
                    {
                        tempFiles.UploadedFiles.Add(new ContentItemFile
                        {
                            FileName      = fileName,
                            PropertyAlias = Constants.Conventions.Media.File,
                            TempFilePath  = file.LocalFileName
                        });
                    }
                }
                else
                {
                    tempFiles.Notifications.Add(new Notification(
                                                    Services.TextService.Localize("speechBubbles/operationFailedHeader"),
                                                    Services.TextService.Localize("media/disallowedFileType"),
                                                    SpeechBubbleIcon.Warning));
                }
            }

            //Different response if this is a 'blueimp' request
            if (Request.GetQueryNameValuePairs().Any(x => x.Key == "origin"))
            {
                var origin = Request.GetQueryNameValuePairs().First(x => x.Key == "origin");
                if (origin.Value == "blueimp")
                {
                    return(Request.CreateResponse(HttpStatusCode.OK,
                                                  tempFiles,
                                                  //Don't output the angular xsrf stuff, blue imp doesn't like that
                                                  new JsonMediaTypeFormatter()));
                }
            }

            return(Request.CreateResponse(HttpStatusCode.OK, tempFiles));
        }