Esempio n. 1
0
        private IMedia CreateNew(MediaItemSave model)
        {
            var mediaType = _mediaTypeService.Get(model.ContentTypeAlias);

            if (mediaType == null)
            {
                throw new InvalidOperationException("No media type found with alias " + model.ContentTypeAlias);
            }
            return(new Cms.Core.Models.Media(model.Name, model.ParentId, mediaType));
        }
            /// <summary>
            ///     Checks if the user has access to post a content item based on whether it's being created or saved.
            /// </summary>
            /// <param name="mediaItem"></param>
            /// <param name="actionContext"></param>
            private async Task <bool> ValidateUserAccessAsync(MediaItemSave mediaItem, ActionExecutingContext actionContext)
            {
                //We now need to validate that the user is allowed to be doing what they are doing.
                //Then if it is new, we need to lookup those permissions on the parent.
                IMedia contentToCheck;
                int    contentIdToCheck;

                switch (mediaItem.Action)
                {
                case ContentSaveAction.Save:
                    contentToCheck   = mediaItem.PersistedContent;
                    contentIdToCheck = contentToCheck.Id;
                    break;

                case ContentSaveAction.SaveNew:
                    contentToCheck = _mediaService.GetById(mediaItem.ParentId);

                    if (mediaItem.ParentId != Constants.System.Root)
                    {
                        contentToCheck   = _mediaService.GetById(mediaItem.ParentId);
                        contentIdToCheck = contentToCheck.Id;
                    }
                    else
                    {
                        contentIdToCheck = mediaItem.ParentId;
                    }

                    break;

                default:
                    //we don't support this for media
                    actionContext.Result = new NotFoundResult();
                    return(false);
                }

                var resource = contentToCheck == null
                    ? new MediaPermissionsResource(contentIdToCheck)
                    : new MediaPermissionsResource(contentToCheck);

                var authorizationResult = await _authorizationService.AuthorizeAsync(
                    actionContext.HttpContext.User,
                    resource,
                    AuthorizationPolicies.MediaPermissionByResource);

                if (!authorizationResult.Succeeded)
                {
                    actionContext.Result = new ForbidResult();
                    return(false);
                }

                return(true);
            }
        /// <summary>
        /// Checks if the user has access to post a content item based on whether it's being created or saved.
        /// </summary>
        /// <param name="mediaItem"></param>
        /// <param name="actionContext"></param>
        private bool ValidateUserAccess(MediaItemSave mediaItem, HttpActionContext actionContext)
        {
            //We now need to validate that the user is allowed to be doing what they are doing.
            //Then if it is new, we need to lookup those permissions on the parent.
            IMedia contentToCheck;
            int    contentIdToCheck;

            switch (mediaItem.Action)
            {
            case ContentSaveAction.Save:
                contentToCheck   = mediaItem.PersistedContent;
                contentIdToCheck = contentToCheck.Id;
                break;

            case ContentSaveAction.SaveNew:
                contentToCheck = _mediaService.GetById(mediaItem.ParentId);

                if (mediaItem.ParentId != Constants.System.Root)
                {
                    contentToCheck   = _mediaService.GetById(mediaItem.ParentId);
                    contentIdToCheck = contentToCheck.Id;
                }
                else
                {
                    contentIdToCheck = mediaItem.ParentId;
                }

                break;

            default:
                //we don't support this for media
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.NotFound);
                return(false);
            }

            if (MediaController.CheckPermissions(
                    actionContext.Request.Properties,
                    _umbracoContextAccessor.UmbracoContext.Security.CurrentUser,
                    _mediaService, _entityService,
                    contentIdToCheck, contentToCheck) == false)
            {
                actionContext.Response = actionContext.Request.CreateUserNoAccessResponse();
                return(false);
            }

            return(true);
        }
Esempio n. 4
0
        public MediaItemDisplay PostSave(
            [ModelBinder(typeof(MediaItemBinder))]
            MediaItemSave contentItem)
        {
            //If we've reached here it means:
            // * Our model has been bound
            // * and validated
            // * any file attachments have been saved to their temporary location for us to use
            // * we have a reference to the DTO object and the persisted object
            // * Permissions are valid

            MapPropertyValues(contentItem);

            //We need to manually check the validation results here because:
            // * We still need to save the entity even if there are validation value errors
            // * Depending on if the entity is new, and if there are non property validation errors (i.e. the name is null)
            //      then we cannot continue saving, we can only display errors
            // * If there are validation errors and they were attempting to publish, we can only save, NOT publish and display
            //      a message indicating this
            if (ModelState.IsValid == false)
            {
                if (ValidationHelper.ModelHasRequiredForPersistenceErrors(contentItem) &&
                    (contentItem.Action == ContentSaveAction.SaveNew))
                {
                    //ok, so the absolute mandatory data is invalid and it's new, we cannot actually continue!
                    // add the modelstate to the outgoing object and throw validation response
                    var forDisplay = Mapper.Map <IMedia, MediaItemDisplay>(contentItem.PersistedContent);
                    forDisplay.Errors = ModelState.ToErrorDictionary();
                    throw new HttpResponseException(Request.CreateValidationErrorResponse(forDisplay));
                }
            }

            //save the item
            var saveStatus = Services.MediaService.WithResult().Save(contentItem.PersistedContent, (int)Security.CurrentUser.Id);

            //return the updated model
            var display = Mapper.Map <IMedia, MediaItemDisplay>(contentItem.PersistedContent);

            //lasty, if it is not valid, add the modelstate to the outgoing object and throw a 403
            HandleInvalidModelState(display);

            //put the correct msgs in
            switch (contentItem.Action)
            {
            case ContentSaveAction.Save:
            case ContentSaveAction.SaveNew:
                if (saveStatus.Success)
                {
                    display.AddSuccessNotification(
                        Services.TextService.Localize("speechBubbles/editMediaSaved"),
                        Services.TextService.Localize("speechBubbles/editMediaSavedText"));
                }
                else
                {
                    AddCancelMessage(display);

                    //If the item is new and the operation was cancelled, we need to return a different
                    // status code so the UI can handle it since it won't be able to redirect since there
                    // is no Id to redirect to!
                    if (saveStatus.Result.StatusType == OperationStatusType.FailedCancelledByEvent && IsCreatingAction(contentItem.Action))
                    {
                        throw new HttpResponseException(Request.CreateValidationErrorResponse(display));
                    }
                }

                break;
            }

            return(display);
        }
        public ActionResult <MediaItemDisplay> PostSave(
            [ModelBinder(typeof(MediaItemBinder))]
            MediaItemSave contentItem)
        {
            //Recent versions of IE/Edge may send in the full client side file path instead of just the file name.
            //To ensure similar behavior across all browsers no matter what they do - we strip the FileName property of all
            //uploaded files to being *only* the actual file name (as it should be).
            if (contentItem.UploadedFiles != null && contentItem.UploadedFiles.Any())
            {
                foreach (var file in contentItem.UploadedFiles)
                {
                    file.FileName = Path.GetFileName(file.FileName);
                }
            }

            //If we've reached here it means:
            // * Our model has been bound
            // * and validated
            // * any file attachments have been saved to their temporary location for us to use
            // * we have a reference to the DTO object and the persisted object
            // * Permissions are valid

            //Don't update the name if it is empty
            if (contentItem.Name.IsNullOrWhiteSpace() == false)
            {
                contentItem.PersistedContent.Name = contentItem.Name;
            }

            MapPropertyValuesForPersistence <IMedia, MediaItemSave>(
                contentItem,
                contentItem.PropertyCollectionDto,
                (save, property) => property.GetValue(),     //get prop val
                (save, property, v) => property.SetValue(v), //set prop val
                null);                                       // media are all invariant

            //we will continue to save if model state is invalid, however we cannot save if critical data is missing.
            //TODO: Allowing media to be saved when it is invalid is odd - media doesn't have a publish phase so suddenly invalid data is allowed to be 'live'
            if (!ModelState.IsValid)
            {
                //check for critical data validation issues, we can't continue saving if this data is invalid
                if (!RequiredForPersistenceAttribute.HasRequiredValuesForPersistence(contentItem))
                {
                    //ok, so the absolute mandatory data is invalid and it's new, we cannot actually continue!
                    // add the model state to the outgoing object and throw validation response
                    MediaItemDisplay forDisplay = _umbracoMapper.Map <MediaItemDisplay>(contentItem.PersistedContent);
                    return(ValidationProblem(forDisplay, ModelState));
                }
            }

            //save the item
            var saveStatus = _mediaService.Save(contentItem.PersistedContent, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(Constants.Security.SuperUserId));

            //return the updated model
            var display = _umbracoMapper.Map <MediaItemDisplay>(contentItem.PersistedContent);

            //lastly, if it is not valid, add the model state to the outgoing object and throw a 403
            if (!ModelState.IsValid)
            {
                return(ValidationProblem(display, ModelState, StatusCodes.Status403Forbidden));
            }

            //put the correct msgs in
            switch (contentItem.Action)
            {
            case ContentSaveAction.Save:
            case ContentSaveAction.SaveNew:
                if (saveStatus.Success)
                {
                    display.AddSuccessNotification(
                        _localizedTextService.Localize("speechBubbles", "editMediaSaved"),
                        _localizedTextService.Localize("speechBubbles", "editMediaSavedText"));
                }
                else
                {
                    AddCancelMessage(display);

                    //If the item is new and the operation was cancelled, we need to return a different
                    // status code so the UI can handle it since it won't be able to redirect since there
                    // is no Id to redirect to!
                    if (saveStatus.Result.Result == OperationResultType.FailedCancelledByEvent && IsCreatingAction(contentItem.Action))
                    {
                        return(ValidationProblem(display));
                    }
                }

                break;
            }

            return(display);
        }
Esempio n. 6
0
 private IMedia?GetExisting(MediaItemSave model)
 {
     return(_mediaService.GetById(Convert.ToInt32(model.Id)));
 }
Esempio n. 7
0
        public MediaItemDisplay PostSave(
            [ModelBinder(typeof(MediaItemBinder))]
            MediaItemSave contentItem)
        {
            //Recent versions of IE/Edge may send in the full clientside file path instead of just the file name.
            //To ensure similar behavior across all browsers no matter what they do - we strip the FileName property of all
            //uploaded files to being *only* the actual file name (as it should be).
            if (contentItem.UploadedFiles != null && contentItem.UploadedFiles.Any())
            {
                foreach (var file in contentItem.UploadedFiles)
                {
                    file.FileName = Path.GetFileName(file.FileName);
                }
            }

            //If we've reached here it means:
            // * Our model has been bound
            // * and validated
            // * any file attachments have been saved to their temporary location for us to use
            // * we have a reference to the DTO object and the persisted object
            // * Permissions are valid

            //Don't update the name if it is empty
            if (contentItem.Name.IsNullOrWhiteSpace() == false)
            {
                contentItem.PersistedContent.Name = contentItem.Name;
            }

            MapPropertyValuesForPersistence <IMedia, MediaItemSave>(
                contentItem,
                contentItem.PropertyCollectionDto,
                (save, property) => property.GetValue(),     //get prop val
                (save, property, v) => property.SetValue(v), //set prop val
                null);                                       // media are all invariant

            //We need to manually check the validation results here because:
            // * We still need to save the entity even if there are validation value errors
            // * Depending on if the entity is new, and if there are non property validation errors (i.e. the name is null)
            //      then we cannot continue saving, we can only display errors
            // * If there are validation errors and they were attempting to publish, we can only save, NOT publish and display
            //      a message indicating this
            if (ModelState.IsValid == false)
            {
                if (!RequiredForPersistenceAttribute.HasRequiredValuesForPersistence(contentItem) &&
                    (contentItem.Action == ContentSaveAction.SaveNew))
                {
                    //ok, so the absolute mandatory data is invalid and it's new, we cannot actually continue!
                    // add the modelstate to the outgoing object and throw validation response
                    var forDisplay = Mapper.Map <MediaItemDisplay>(contentItem.PersistedContent);
                    forDisplay.Errors = ModelState.ToErrorDictionary();
                    throw new HttpResponseException(Request.CreateValidationErrorResponse(forDisplay));
                }
            }

            //save the item
            var saveStatus = Services.MediaService.Save(contentItem.PersistedContent, (int)Security.CurrentUser.Id);

            //return the updated model
            var display = Mapper.Map <MediaItemDisplay>(contentItem.PersistedContent);

            //lasty, if it is not valid, add the modelstate to the outgoing object and throw a 403
            HandleInvalidModelState(display);

            //put the correct msgs in
            switch (contentItem.Action)
            {
            case ContentSaveAction.Save:
            case ContentSaveAction.SaveNew:
                if (saveStatus.Success)
                {
                    display.AddSuccessNotification(
                        Services.TextService.Localize("speechBubbles/editMediaSaved"),
                        Services.TextService.Localize("speechBubbles/editMediaSavedText"));
                }
                else
                {
                    AddCancelMessage(display);

                    //If the item is new and the operation was cancelled, we need to return a different
                    // status code so the UI can handle it since it won't be able to redirect since there
                    // is no Id to redirect to!
                    if (saveStatus.Result.Result == OperationResultType.FailedCancelledByEvent && IsCreatingAction(contentItem.Action))
                    {
                        throw new HttpResponseException(Request.CreateValidationErrorResponse(display));
                    }
                }

                break;
            }

            return(display);
        }