Example #1
0
        private async Task <CustomEntityRenderDetails> GetCustomEntityModel(PageActionRoutingState state)
        {
            var query = new GetCustomEntityRenderDetailsByIdQuery();

            query.CustomEntityId = state.PageRoutingInfo.CustomEntityRoute.CustomEntityId;
            query.PageId         = state.PageData.PageId;

            // If we're editing the custom entity, we need to get the version we're editing, otherwise just get latest
            if (state.InputParameters.IsEditingCustomEntity)
            {
                if (state.InputParameters.VersionId.HasValue)
                {
                    query.CustomEntityVersionId = state.InputParameters.VersionId;
                    query.PublishStatus         = PublishStatusQuery.SpecificVersion;
                }
                else
                {
                    query.PublishStatus = state.VisualEditorState.GetPublishStatusQuery();
                }
            }
            else if (state.IsCofoundryAdminUser)
            {
                query.PublishStatus = PublishStatusQuery.Latest;
            }

            var model = await _queryExecutor.ExecuteAsync(query);

            return(model);
        }
Example #2
0
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var pageQuery       = GetPageRoutingInfoQuery(state);
            var pageRoutingInfo = await _queryExecutor.ExecuteAsync(pageQuery);

            state.PageRoutingInfo = pageRoutingInfo;
        }
Example #3
0
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // The ambient auth scheme might not be the cofoundry admin scheme
            // So we will attempt to find the cofoundry user to execute the contoller with
            // falling back to the user authenticated with the ambient scheme
            state.AmbientUserContext = await _userContextService.GetCurrentContextAsync();

            IUserContext cofoundryUserContext = null;

            if (state.AmbientUserContext.IsCofoundryUser())
            {
                cofoundryUserContext = state.AmbientUserContext;
            }
            else
            {
                cofoundryUserContext = await _userContextService.GetCurrentContextByUserAreaAsync(CofoundryAdminUserArea.Code);
            }

            if (cofoundryUserContext.IsCofoundryUser())
            {
                state.IsCofoundryAdminUser           = true;
                state.CofoundryAdminUserContext      = cofoundryUserContext;
                state.CofoundryAdminExecutionContext = _executionContextFactory.Create(state.CofoundryAdminUserContext);
            }
        }
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            if (controller == null)
            {
                throw new ArgumentNullException(nameof(controller));
            }
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }
            EntityInvalidOperationException.ThrowIfNull(state, r => r.AmbientUserContext);

            // If no page (404) skip this step - it will be handled later
            // Access rules don't apply to Cofoundry admin users, so skip this step
            var isAmbientContextCofoundryAdmin = state.AmbientUserContext.IsCofoundryUser();

            if (state.PageRoutingInfo == null || isAmbientContextCofoundryAdmin)
            {
                var skipReason = isAmbientContextCofoundryAdmin ? "User is Cofoundry admin user" : "no page found";
                _logger.LogDebug("Skipping access rule validation step, {SkipReason}.", skipReason);

                return;
            }

            var accessRuleViolation = await FindAccessRuleViolation(state);

            if (accessRuleViolation == null)
            {
                _logger.LogDebug("No access rule violations found.");
            }
            else
            {
                EnforceRuleViolation(controller, state, accessRuleViolation);
            }
        }
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var query = new GetPageRenderDetailsByIdQuery();

            query.PageId = state.PageRoutingInfo.PageRoute.PageId;

            if (state.InputParameters.IsEditingCustomEntity)
            {
                // If we're editing a custom entity, then get the latest version of the page
                query.PublishStatus = PublishStatusQuery.Latest;
            }
            else if (state.InputParameters.VersionId.HasValue)
            {
                query.PublishStatus = PublishStatusQuery.SpecificVersion;
                query.PageVersionId = state.InputParameters.VersionId;
            }
            else
            {
                query.PublishStatus = state.VisualEditorState.GetPublishStatusQuery();
            }

            state.PageData = await _queryExecutor.ExecuteAsync(query);

            // if no data is found there was an issue with creating a draft earlier on.
            if (state.PageData == null && state.VisualEditorState.VisualEditorMode == VisualEditorMode.Edit)
            {
                throw new Exception("Draft version missing for page id " + query.PageId);
            }

            // If we can't find any page data, then return a 404
            if (state.PageData == null)
            {
                state.Result = await _notFoundViewHelper.GetViewAsync(controller);
            }
        }
        private void EnforceRuleViolation(Controller controller, PageActionRoutingState state, EntityAccessRuleSet accessRuleViolation)
        {
            if (!state.AmbientUserContext.IsSignedIn() && accessRuleViolation.ShouldTryRedirect())
            {
                _logger.LogDebug("User not authenticated, redirecting to sign in page for user area {UserAreaCodeForLoginRedirect}.", accessRuleViolation.UserAreaCodeForSignInRedirect);
                var challengeScheme = AuthenticationSchemeNames.UserArea(accessRuleViolation.UserAreaCodeForSignInRedirect);
                state.Result = new ChallengeResult(challengeScheme);
                return;
            }

            _logger.LogDebug("Processing violation action {ViolationAction}.", accessRuleViolation.ViolationAction);
            switch (accessRuleViolation.ViolationAction)
            {
            case AccessRuleViolationAction.NotFound:
                // Set the route to null and the IGetNotFoundRouteRoutingStep will figure out the correct result
                state.PageRoutingInfo = null;
                break;

            case AccessRuleViolationAction.Error:
                // Throw an exception, which should be picked up by the global handler and dealt with accordingly.
                throw new AccessRuleViolationException($"User is not permitted to access {state.InputParameters.Path}.");

            default:
                throw new NotImplementedException($"{nameof(AccessRuleViolationAction)}.{accessRuleViolation.ViolationAction} not implemented.");
            }
            ;
        }
Example #7
0
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            state.UserContext = _userContextService.GetCurrentContext();

            // Work out whether to view the page in live/draft/edit mode.
            // We use live by default (for logged out users) or for authenticated
            // users we can show draft too.
            var visualEditorMode = VisualEditorMode.Live;

            if (state.UserContext.IsCofoundryUser())
            {
                if (state.InputParameters.VersionId.HasValue)
                {
                    visualEditorMode = VisualEditorMode.SpecificVersion;
                }
                else if (!Enum.TryParse(state.InputParameters.VisualEditorMode, true, out visualEditorMode))
                {
                    visualEditorMode = VisualEditorMode.Any;
                }
            }
            else if (_contentSettings.AlwaysShowUnpublishedData)
            {
                // We can optionally set the visual editor mode to any - ie show draft and published pages
                // This is used in scenarios where devs are making modifications against a live db using a
                // local debug version of the site but aren't ready to publish the pages yet.
                visualEditorMode = VisualEditorMode.Any;
            }
            state.VisualEditorMode = visualEditorMode;

            return(Task.FromResult(true));
        }
Example #8
0
        public async Task <ActionResult> Page(
            string path,
            string mode,
            int?version     = null,
            string editType = "entity"
            )
        {
            // Init state
            var state = new PageActionRoutingState();

            state.Locale          = _locale;
            state.InputParameters = new PageActionInputParameters()
            {
                Path                  = path,
                VisualEditorMode      = mode,
                VersionId             = version,
                IsEditingCustomEntity = editType == "entity"
            };

            // Run through the pipline in order
            foreach (var method in _pageActionRoutingStepFactory.Create())
            {
                await method.ExecuteAsync(this, state);

                // If we get an action result, do an early return
                if (state.Result != null)
                {
                    return(state.Result);
                }
            }

            // We should never get here!
            throw new InvalidOperationException("Unknown Page Routing State");
        }
Example #9
0
        public async Task SetCacheAsync(IEditablePageViewModel vm, PageActionRoutingState state)
        {
            var siteViewerMode     = state.VisualEditorMode;
            var publishStatusQuery = state.VisualEditorMode.ToPublishStatusQuery();
            var pageVersions       = state.PageRoutingInfo.PageRoute.Versions;

            // Force a viewer mode
            if (siteViewerMode == VisualEditorMode.Any)
            {
                var version = state.PageRoutingInfo.GetVersionRoute(
                    state.InputParameters.IsEditingCustomEntity,
                    state.VisualEditorMode.ToPublishStatusQuery(),
                    state.InputParameters.VersionId);

                switch (version.WorkFlowStatus)
                {
                case WorkFlowStatus.Draft:
                    siteViewerMode = VisualEditorMode.Draft;
                    break;

                case WorkFlowStatus.Published:
                    siteViewerMode = VisualEditorMode.Live;
                    break;

                default:
                    throw new InvalidOperationException("WorkFlowStatus." + version.WorkFlowStatus + " is not valid for VisualEditorMode.Any");
                }
            }

            var pageResponseData = new PageResponseData();

            pageResponseData.Page                      = vm;
            pageResponseData.VisualEditorMode          = siteViewerMode;
            pageResponseData.PageRoutingInfo           = state.PageRoutingInfo;
            pageResponseData.HasDraftVersion           = state.PageRoutingInfo.GetVersionRoute(state.InputParameters.IsEditingCustomEntity, PublishStatusQuery.Draft, null) != null;
            pageResponseData.Version                   = state.PageRoutingInfo.GetVersionRoute(state.InputParameters.IsEditingCustomEntity, publishStatusQuery, state.InputParameters.VersionId);
            pageResponseData.CofoundryAdminUserContext = state.CofoundryAdminUserContext;

            var customEntityDefinitionCode = state.PageRoutingInfo.PageRoute.CustomEntityDefinitionCode;

            if (!string.IsNullOrEmpty(customEntityDefinitionCode))
            {
                var definitionQuery = new GetCustomEntityDefinitionSummaryByCodeQuery(customEntityDefinitionCode);
                pageResponseData.CustomEntityDefinition = await _queryExecutor.ExecuteAsync(definitionQuery);
            }

            if (state.InputParameters.IsEditingCustomEntity)
            {
                pageResponseData.PageVersion = pageVersions.GetVersionRouting(PublishStatusQuery.Latest);
            }
            else
            {
                pageResponseData.PageVersion = pageVersions.GetVersionRouting(publishStatusQuery, state.InputParameters.VersionId);
            }

            _pageRenderDataCache.Set(pageResponseData);
        }
Example #10
0
        public void SetCache(IEditablePageViewModel vm, PageActionRoutingState state)
        {
            var siteViewerMode      = state.VisualEditorMode;
            var workFlowStatusQuery = state.VisualEditorMode.ToWorkFlowStatusQuery();
            var pageVersions        = state.PageRoutingInfo.PageRoute.Versions;

            // Force a viewer mode
            if (siteViewerMode == VisualEditorMode.Any)
            {
                var version = state.PageRoutingInfo.GetVersionRoute(
                    state.InputParameters.IsEditingCustomEntity,
                    state.VisualEditorMode.ToWorkFlowStatusQuery(),
                    state.InputParameters.VersionId);

                switch (version.WorkFlowStatus)
                {
                case WorkFlowStatus.Draft:
                    siteViewerMode = VisualEditorMode.Draft;
                    break;

                case WorkFlowStatus.Published:
                    siteViewerMode = VisualEditorMode.Live;
                    break;

                default:
                    throw new ApplicationException("WorkFlowStatus." + version.WorkFlowStatus + " is not valid for VisualEditorMode.Any");
                }
            }

            var pageResponseData = new PageResponseData();

            pageResponseData.Page                = vm;
            pageResponseData.VisualEditorMode    = siteViewerMode;
            pageResponseData.PageRoutingInfo     = state.PageRoutingInfo;
            pageResponseData.HasDraftVersion     = state.PageRoutingInfo.GetVersionRoute(state.InputParameters.IsEditingCustomEntity, WorkFlowStatusQuery.Draft, null) != null;
            pageResponseData.Version             = state.PageRoutingInfo.GetVersionRoute(state.InputParameters.IsEditingCustomEntity, workFlowStatusQuery, state.InputParameters.VersionId);
            pageResponseData.IsCustomEntityRoute = pageResponseData.Version is CustomEntityVersionRoute;

            if (!string.IsNullOrEmpty(state.PageRoutingInfo.PageRoute.CustomEntityDefinitionCode))
            {
                pageResponseData.CustomEntityDefinition = _queryExecutor.GetById <CustomEntityDefinitionSummary>(state.PageRoutingInfo.PageRoute.CustomEntityDefinitionCode);
            }

            if (state.InputParameters.IsEditingCustomEntity)
            {
                pageResponseData.PageVersion = pageVersions.GetVersionRouting(WorkFlowStatusQuery.Latest);
            }
            else
            {
                pageResponseData.PageVersion = pageVersions.GetVersionRouting(workFlowStatusQuery, state.InputParameters.VersionId);
            }

            _pageRenderDataCache.Set(pageResponseData);
        }
Example #11
0
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // TODO: Come up with a better caching policy, but for now
            // don't cache if we're logged into Cofoundry Admin
            if (state.UserContext.IsCofoundryUser())
            {
                controller.Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
                controller.Response.Cache.SetNoStore();
            }

            return(Task.FromResult(true));
        }
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var settings = await _queryExecutor.ExecuteAsync(new GetSettingsQuery <InternalSettings>());

            if (!settings.IsSetup)
            {
                var setup = _setupPageActionFactory.GetSetupPageAction(controller);
                if (setup == null)
                {
                    throw new Exception("ISetupPageActionFactory returned no action.");
                }
                state.Result = setup;
            }
        }
Example #13
0
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // The ambient auth schema might not be the cofoundry admin scheme
            // So we will attempt to find the cofoundry user to execute the contoller with
            // falling back to the user authenticated with the ambient scheme
            state.AmbientUserContext = await _userContextService.GetCurrentContextAsync();

            IUserContext cofoundryUserContext = null;

            if (state.AmbientUserContext.IsCofoundryUser())
            {
                cofoundryUserContext = state.AmbientUserContext;
            }
            else
            {
                cofoundryUserContext = await _userContextService.GetCurrentContextByUserAreaAsync(CofoundryAdminUserArea.AreaCode);
            }

            if (cofoundryUserContext.IsCofoundryUser())
            {
                state.IsCofoundryAdminUser           = true;
                state.CofoundryAdminUserContext      = cofoundryUserContext;
                state.CofoundryAdminExecutionContext = _executionContextFactory.Create(state.CofoundryAdminUserContext);
            }

            // Work out whether to view the page in live/draft/edit mode.
            // We use live by default (for logged out users) or for authenticated
            // users we can show draft too.
            var visualEditorMode = VisualEditorMode.Live;

            if (state.IsCofoundryAdminUser)
            {
                if (state.InputParameters.VersionId.HasValue)
                {
                    visualEditorMode = VisualEditorMode.SpecificVersion;
                }
                else if (!Enum.TryParse(state.InputParameters.VisualEditorMode, true, out visualEditorMode))
                {
                    visualEditorMode = VisualEditorMode.Any;
                }
            }
            else if (_contentSettings.AlwaysShowUnpublishedData)
            {
                // We can optionally set the visual editor mode to any - ie show draft and published pages
                // This is used in scenarios where devs are making modifications against a live db using a
                // local debug version of the site but aren't ready to publish the pages yet.
                visualEditorMode = VisualEditorMode.Any;
            }
            state.VisualEditorMode = visualEditorMode;
        }
Example #14
0
        private async Task <ActionResult> GetPageViewResult(Controller controller, PageActionRoutingState state)
        {
            IEditablePageViewModel vm;
            var pageRoutingInfo = state.PageRoutingInfo;

            // Some page types have thier own specific view models which custom data
            switch (pageRoutingInfo.PageRoute.PageType)
            {
            case PageType.NotFound:
                controller.Response.StatusCode = (int)HttpStatusCode.NotFound;
                // Not sure why we're not using a NotFoundViewModel here, but this is old
                // and untested functionality. Content managable not found pages will need to be looked at at a later date
                var notFoundPageParams = new PageViewModelBuilderParameters(state.PageData, state.VisualEditorMode);
                vm = await _pageViewModelBuilder.BuildPageViewModelAsync(notFoundPageParams);

                break;

            case PageType.CustomEntityDetails:
                var model = await GetCustomEntityModel(state);

                var customEntityParams = new CustomEntityDetailsPageViewModelBuilderParameters(state.PageData, state.VisualEditorMode, model);

                vm = await BuildCustomEntityViewModelAsync(state.PageData.Template.CustomEntityModelType, customEntityParams);

                break;

            //case PageType.Error:
            //    Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            //    vm = _pageViewModelMapper.MapPage(page, siteViewerMode);
            //    break;
            default:
                var pageParams = new PageViewModelBuilderParameters(state.PageData, state.VisualEditorMode);
                vm = await _pageViewModelBuilder.BuildPageViewModelAsync(pageParams);

                break;
            }


            // set cache
            SetCache(vm, state);

            var result = new ViewResult()
            {
                ViewData = new ViewDataDictionary(vm),
                ViewName = state.PageData.Template.FullPath
            };

            return(result);
        }
        private async Task <EntityAccessRuleSet> FindAccessRuleViolation(PageActionRoutingState state)
        {
            var accessRuleViolation = state.PageRoutingInfo.ValidateAccess(state.AmbientUserContext);

            // If the user associated with the ambient context is not authorized, then we need to check
            // to see if the user is logged into any other user areas that are permitted to access the route.
            if (accessRuleViolation != null)
            {
                // For user areas, only the topmost ruleset matters
                var relavantRuleSet = EnumerateAccessRuleSets(state.PageRoutingInfo).FirstOrDefault();

                // Find any other user areas to check
                // more than one custom user area should be a rare occurence
                // more than two is rare indeed, but we should account for it and use determanistic ordering
                var userAreaCodesToCheck = relavantRuleSet
                                           .AccessRules
                                           .Select(r => r.UserAreaCode)
                                           .Where(r => r != state.AmbientUserContext.UserArea?.UserAreaCode)
                                           .Distinct()
                                           .OrderBy(r => r);

                foreach (var userAreaCode in userAreaCodesToCheck)
                {
                    var context = await _userContextService.GetCurrentContextByUserAreaAsync(userAreaCode);

                    var ruleViolation = state.PageRoutingInfo.ValidateAccess(context);
                    if (ruleViolation == null)
                    {
                        _logger.LogDebug(
                            "User is logged into non-default user area {UserAreaCode} that passes access rule validation, switching ambient context to userId {UserId}.",
                            context.UserArea.UserAreaCode,
                            context.UserId
                            );

                        // the user is logged into an alternative user area that matches one of the rules
                        // so we should set it as the ambient user context. This mimics the behaviour of
                        // AuthorizeAttribute in ASP.NET where the auth attribute determines the ambient
                        // auth scheme.
                        await _userSessionService.SetAmbientUserAreaAsync(context.UserArea.UserAreaCode);

                        state.AmbientUserContext = context;
                        accessRuleViolation      = null;
                        break;
                    }
                }
            }

            return(accessRuleViolation);
        }
Example #16
0
        private GetPageRoutingInfoByPathQuery GetPageRoutingInfoQuery(PageActionRoutingState state)
        {
            var pageQuery = new GetPageRoutingInfoByPathQuery()
            {
                Path = state.InputParameters.Path,
                IncludeUnpublished = state.VisualEditorState.VisualEditorMode != VisualEditorMode.Live
            };

            if (state.Locale != null)
            {
                pageQuery.LocaleId = state.Locale.LocaleId;
            }

            return(pageQuery);
        }
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var pageRoutingInfo = state.PageRoutingInfo;
            if (pageRoutingInfo == null) return Task.CompletedTask;

            if (state.InputParameters.IsEditingCustomEntity &&
                (pageRoutingInfo.CustomEntityRoute == null 
                || !state.IsCofoundryAdminUser
                || !_permissionValidationService.HasCustomEntityPermission<CustomEntityUpdatePermission>(pageRoutingInfo.CustomEntityRoute.CustomEntityDefinitionCode, state.CofoundryAdminUserContext))
                )
            {
                state.InputParameters.IsEditingCustomEntity = false;
            }

            return Task.CompletedTask;
        }
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // TODO: Come up with a better caching policy, but for now
            // don't cache if we're logged into Cofoundry Admin
            if (state.IsCofoundryAdminUser)
            {
                var headers = controller.Response.GetTypedHeaders();
                headers.CacheControl = new CacheControlHeaderValue()
                {
                    NoCache = true,
                    NoStore = true,
                };
            }

            return(Task.CompletedTask);
        }
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var internalSettings = _queryExecutor.Get <InternalSettings>();

            if (!internalSettings.IsSetup)
            {
                var setup = _setupPageActionFactory.GetSetupPageAction(controller);
                if (setup == null)
                {
                    throw new ApplicationException("ISetupPageActionFactory returned no action.");
                }
                state.Result = setup;
            }

            return(Task.FromResult(true));
        }
Example #20
0
        private async Task <CustomEntityRenderDetails> GetCustomEntityModel(PageActionRoutingState state)
        {
            var query = new GetCustomEntityRenderDetailsByIdQuery();

            query.CustomEntityId = state.PageRoutingInfo.CustomEntityRoute.CustomEntityId;
            query.PageTemplateId = state.PageData.Template.PageTemplateId;

            // If we're editing the custom entity, we need to get the version we're editing, otherwise just get latest
            if (state.InputParameters.IsEditingCustomEntity)
            {
                query.WorkFlowStatus        = state.VisualEditorMode.ToWorkFlowStatusQuery();
                query.CustomEntityVersionId = state.InputParameters.VersionId;
            }
            var model = await _queryExecutor.ExecuteAsync(query);

            return(model);
        }
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // Ensure that non-authenticated users can't access previous versions
            if (state.VisualEditorState.VisualEditorMode != VisualEditorMode.SpecificVersion)
            {
                state.InputParameters.VersionId = null;
            }
            else if (state.PageRoutingInfo != null)
            {
                var versionRoute = state.PageRoutingInfo.GetVersionRoute(
                    state.InputParameters.IsEditingCustomEntity,
                    state.VisualEditorState.GetPublishStatusQuery(),
                    state.InputParameters.VersionId);

                // If this isn't an old version of a page, set the VisualEditorMode accordingly.
                if (versionRoute != null)
                {
                    if (versionRoute.WorkFlowStatus == WorkFlowStatus.Draft)
                    {
                        var url = _pageRouteLibrary.VisualEditor(
                            state.PageRoutingInfo,
                            VisualEditorMode.Preview,
                            state.InputParameters.IsEditingCustomEntity
                            );

                        state.Result = controller.Redirect(url);
                    }
                    else if (versionRoute.IsLatestPublishedVersion && state.PageRoutingInfo.IsPublished())
                    {
                        var url = _pageRouteLibrary.VisualEditor(
                            state.PageRoutingInfo,
                            VisualEditorMode.Live,
                            state.InputParameters.IsEditingCustomEntity
                            );

                        state.Result = controller.Redirect(url);
                    }
                }
                else
                {
                    // Could not find a version, id must be invalid
                    state.Result = await _notFoundViewHelper.GetViewAsync(controller);
                }
            }
        }
Example #22
0
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var completedTask = Task.FromResult(true);

            var pageRoutingInfo = state.PageRoutingInfo;

            if (pageRoutingInfo == null)
            {
                return(completedTask);
            }

            if (pageRoutingInfo.CustomEntityRoute == null && state.InputParameters.IsEditingCustomEntity)
            {
                state.InputParameters.IsEditingCustomEntity = false;
            }

            return(completedTask);
        }
Example #23
0
        private async Task <ActionResult> GetPageViewResult(Controller controller, PageActionRoutingState state)
        {
            IEditablePageViewModel vm;
            var pageRoutingInfo = state.PageRoutingInfo;

            // Some page types have thier own specific view models which custom data
            switch (pageRoutingInfo.PageRoute.PageType)
            {
            case PageType.NotFound:
                controller.Response.StatusCode = (int)HttpStatusCode.NotFound;
                vm = _pageViewModelMapper.Map(state.PageData, state.VisualEditorMode);
                break;

            case PageType.CustomEntityDetails:
                var model = await GetCustomEntityModel(state);

                vm = _pageViewModelMapper.MapCustomEntityModel(state.PageData.Template.CustomEntityModelType, state.PageData, model, state.VisualEditorMode);
                break;

            //case PageType.Error:
            //    Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            //    vm = _pageViewModelMapper.Map(page, siteViewerMode);
            //    break;
            default:
                vm = _pageViewModelMapper.Map(state.PageData, state.VisualEditorMode);
                break;
            }


            // set cache
            SetCache(vm, state);

            var result = new ViewResult()
            {
                ViewData = new ViewDataDictionary(vm),
                ViewName = state.PageData.Template.FullPath
            };

            return(result);
        }
Example #24
0
        /// <summary>
        /// Action for all dynamic page routes.
        /// </summary>
        /// <param name="path">The raw, relative path of the page without querystring.</param>
        /// <param name="mode">
        /// This string maps to the enum <see cref="VisualEditorMode"/> and is used in the
        /// visual editor in the admin site. The value is not parsed here as the admin panel
        /// may not be installed, instead it should be parsed in the admin panel
        /// <see cref="IVisualEditorStateService"/> implementation.
        /// </param>
        /// <param name="version">
        /// Optionally a VersionId can be specified to
        /// view a specific version of a page or custom entity.
        /// </param>
        /// <param name="editType">
        /// When routing to a custom entity this determines if we are editing the
        /// custom entity or the overall page template. Both cannot be edited at the same
        /// time since it would be confusing to manage both version states.
        /// </param>
        public async Task <IActionResult> Page(
            string path,
            string mode,
            int?version     = null,
            string editType = "entity"
            )
        {
            _logger.LogInformation("Processing route {Path} with visual editor mode '{VisualEditorMode}', page version Id '{PageVersionId}' and edit-type '{EditType}'", path, mode, version, editType);

            // Init state
            var state = new PageActionRoutingState();

            state.Locale = await GetLocaleAsync();

            state.InputParameters = new PageActionInputParameters()
            {
                Path                  = path,
                VersionId             = version,
                IsEditingCustomEntity = editType == "entity"
            };


            // Run through the pipline in order
            foreach (var method in _pageActionRoutingStepFactory.Create())
            {
                _logger.LogDebug("Executing step {StepType}", method.GetType());
                await method.ExecuteAsync(this, state);

                // If we get an action result, do an early return
                if (state.Result != null)
                {
                    _logger.LogDebug("Step {StepType} returned a result.", method.GetType());
                    return(state.Result);
                }
            }

            // We should never get here!
            throw new InvalidOperationException("Unknown Page Routing State");
        }
Example #25
0
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // Find a 404 page if a version exists.
            if (state.PageRoutingInfo == null)
            {
                // First check for a rewrite rule and apply it
                state.Result = await GetRewriteResult(controller);

                if (state.Result != null)
                {
                    return;
                }

                // else try and find a 404 page route
                state.PageRoutingInfo = await TryFindNotFoundPageRoute(state.InputParameters.Path, state.VisualEditorMode);

                // If we still can't find a 404, fall back to the generic 404 view
                if (state.PageRoutingInfo == null)
                {
                    state.Result = await _notFoundViewHelper.GetViewAsync();
                }
            }
        }
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var pageRoutingInfo = state.PageRoutingInfo;

            if (pageRoutingInfo == null || state.VisualEditorState.VisualEditorMode != VisualEditorMode.Edit)
            {
                return(Task.CompletedTask);
            }

            if (pageRoutingInfo.CustomEntityRoute != null &&
                state.InputParameters.IsEditingCustomEntity
                )
            {
                _permissionValidationService.EnforceCustomEntityPermission <CustomEntityUpdatePermission>(pageRoutingInfo.CustomEntityRoute.CustomEntityDefinitionCode, state.CofoundryAdminUserContext);
            }

            if (!state.InputParameters.IsEditingCustomEntity)
            {
                _permissionValidationService.EnforcePermission <PageUpdatePermission>(state.CofoundryAdminUserContext);
            }

            return(Task.CompletedTask);
        }
        public Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            // Ensure that non-authenticated users can't access previous versions
            if (state.VisualEditorMode != VisualEditorMode.SpecificVersion)
            {
                state.InputParameters.VersionId = null;
            }
            else if (state.PageRoutingInfo != null)
            {
                var versionRoute = state.PageRoutingInfo.GetVersionRoute(
                    state.InputParameters.IsEditingCustomEntity,
                    state.VisualEditorMode.ToWorkFlowStatusQuery(),
                    state.InputParameters.VersionId);

                // If this isn't an old version of a page, set the VisualEditorMode accordingly.
                if (versionRoute != null)
                {
                    switch (versionRoute.WorkFlowStatus)
                    {
                    case Cofoundry.Domain.WorkFlowStatus.Draft:
                        state.VisualEditorMode = VisualEditorMode.Draft;
                        break;

                    case Cofoundry.Domain.WorkFlowStatus.Published:
                        state.VisualEditorMode = VisualEditorMode.Live;
                        break;
                    }
                }
                else
                {
                    // Could not find a version, id must be invalid
                    state.InputParameters.VersionId = null;
                }
            }

            return(Task.FromResult(true));
        }
Example #28
0
        public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
        {
            var pageRoutingInfo = state.PageRoutingInfo;

            if (pageRoutingInfo == null)
            {
                return;
            }

            // If there's no draft version and we're in edit mode for 'Pages' then
            // create one and re-run the query
            var publishStatus = state.VisualEditorState.GetPublishStatusQuery();

            if (!state.InputParameters.IsEditingCustomEntity &&
                publishStatus != PublishStatusQuery.Published &&
                publishStatus != PublishStatusQuery.SpecificVersion &&
                state.IsCofoundryAdminUser)
            {
                var versionRouting = pageRoutingInfo.PageRoute.Versions.GetVersionRouting(publishStatus);
                if (versionRouting == null)
                {
                    var command = new AddPageDraftVersionCommand()
                    {
                        PageId = pageRoutingInfo.PageRoute.PageId
                    };
                    await _commandExecutor.ExecuteAsync(command, state.CofoundryAdminExecutionContext);

                    var pageQuery = GetPageRoutingInfoQuery(state);
                    pageRoutingInfo = await _queryExecutor.ExecuteAsync(pageQuery);
                }
            }

            if (pageRoutingInfo.CustomEntityRoute != null &&
                pageRoutingInfo.PageRoute.PageType == PageType.CustomEntityDetails)
            {
                var correctUrl = pageRoutingInfo.CustomEntityRouteRule.MakeUrl(pageRoutingInfo.PageRoute, pageRoutingInfo.CustomEntityRoute);
                if (!state.InputParameters.Path.Equals(correctUrl.TrimStart('/'), StringComparison.OrdinalIgnoreCase))
                {
                    Debug.WriteLine("Incorrect Custom Entity Url detected, redirecting from " + state.InputParameters.Path + " to " + correctUrl);
                    state.Result = new RedirectResult(correctUrl, true);
                }
                else if (state.InputParameters.IsEditingCustomEntity &&
                         publishStatus != PublishStatusQuery.Published &&
                         publishStatus != PublishStatusQuery.SpecificVersion &&
                         state.IsCofoundryAdminUser)
                {
                    var versionRouting = pageRoutingInfo.CustomEntityRoute.Versions.GetVersionRouting(publishStatus);
                    if (versionRouting == null)
                    {
                        // if no draft version for route, add one.
                        var addDraftVersionCommand = new AddCustomEntityDraftVersionCommand()
                        {
                            CustomEntityId = pageRoutingInfo.CustomEntityRoute.CustomEntityId
                        };
                        await _commandExecutor.ExecuteAsync(addDraftVersionCommand, state.CofoundryAdminExecutionContext);

                        var pageQuery = GetPageRoutingInfoQuery(state);
                        pageRoutingInfo = await _queryExecutor.ExecuteAsync(pageQuery);
                    }
                }
            }

            state.PageRoutingInfo = pageRoutingInfo;
        }
 public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
 {
     state.VisualEditorState = await _visualEditorStateService.GetCurrentAsync();
 }
Example #30
0
 public async Task ExecuteAsync(Controller controller, PageActionRoutingState state)
 {
     state.Result = await GetPageViewResult(controller, state);
 }