public async Task <IHttpActionResult> GetLayersByUriAsync(string portalUri, string pageUri, CancellationToken cancellationToken)
        {
            var portal = await _portalManager.FindByUriAsync(portalUri, PortalField.All, cancellationToken);

            await ApiSecurity.AuthorizeAsync(portal, AccessPermission.CanView, cancellationToken);

            var pageLayers = await _portalManager.GetPageLayersByUriAsync(portal, pageUri, cancellationToken);

            if (pageLayers?.ContentPage == null)
            {
                return(NotFound());
            }

            var compilerResult = await _portalCompiler.CompileAsync(
                new PortalCompilerOptions
                (
                    portal : portal,
                    contentPage : pageLayers.ContentPage,
                    masterPages : pageLayers.MasterPages.ToImmutableArray()
                ),
                cancellationToken);

            return(Ok(ModelMapper.ToPageLayersDto(portal, compilerResult)));
        }
Beispiel #2
0
        /// <summary>
        /// Creates a <see cref="EngineResultViewModel" /> that represents page information.
        /// Asynchronous calls cannot be inlined so we keep these in one method body.
        /// </summary>
        /// <param name="portal">The portal which owns the page.</param>
        /// <param name="pageLayers">The page layers that can be compiled by <see cref="PortalCompiler" />.</param>
        /// <param name="actionLink">A deserialized form of an action link.</param>
        /// <param name="authTicket">A deserialized form of an authentication ticket.</param>
        /// <param name="addEventLogItem">Logs the current request if set to <c>true</c>.</param>
        /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param>
        /// <returns>
        /// A task that represents the asynchronous operation.
        /// </returns>
        private async Task <EngineResultViewModel> CreateResultAsync(
            SecurityResult security,
            PortalItem portal,
            PageLayers pageLayers,
            ActionLink actionLink,
            AuthTicket authTicket,
            bool addEventLogItem,
            CancellationToken cancellationToken)
        {
            var result = new EngineResultViewModel
            {
                AnonymId = Request.GetAnonymId() ?? GuidUtility.NewSequentialGuid(), // Gets the Anonym User ID from the request.
                Portal   = new EnginePortalViewModel
                {
                    Uri          = portal.Uri,
                    Name         = portal.Name,
                    Description  = portal.Description,
                    GATrackingId = portal.GATrackingId,
                    Project      = portal.Project
                },
                Security = security
            };
            var cookiePath = portal.Uri;
            var contact    = default(ContactItem);

            Response.Cookies.Remove(ResourceKeys.ContactTokenCookieName);

            if (authTicket != null)
            {
                // Generate a bearer token for the ticket to authenticate
                // HTTP requests are from client side if the specified contact exists.

                contact = await _projectManager.GetContactByIdAsync(authTicket.Id, cancellationToken);

                if (contact != null)
                {
                    result.Identity      = AuthUtility.Create(contact);
                    result.IdentityToken = AuthUtility.Protect(result.Identity);
                    Response.Cookies.Add(new HttpCookie(ResourceKeys.ContactTokenCookieName, result.IdentityToken)
                    {
                        Path = cookiePath, HttpOnly = true
                    });
                }
            }
            else if (actionLink?.ContactId != null)
            {
                // Generate a simple identity without a bearer token
                // to identify a user without authenticating him/her.

                contact = await _projectManager.GetContactByIdAsync((int)actionLink.ContactId, cancellationToken);

                if (contact != null)
                {
                    result.Identity = AuthUtility.Create(contact);
                }
            }

            // Compile the page and replace all the placeholders, action links, etc.

            var compilerResult = await _portalCompiler.CompileAsync(
                new PortalCompilerOptions
                (
                    portal : portal,
                    contentPage : pageLayers.ContentPage,
                    masterPages : pageLayers.MasterPages.ToImmutableArray(),
                    properties : new PropertyDictionary
            {
                [StringTemplate.IdentityIdProperty] = result.Identity?.Id,
                [PortalAppResources.IdentityProperty] = contact
            }.ToImmutableDictionary(),
                    compilerFlags : PortalCompilerFlags.MergeMasterAndContent | PortalCompilerFlags.InterpolateHtmlContent
                ),
                cancellationToken);

            result.Page = new EnginePageViewModel
            {
                Uri          = compilerResult.CompiledPage.Uri,
                Name         = compilerResult.CompiledPage.Name,
                Description  = compilerResult.CompiledPage.Description,
                HtmlContent  = compilerResult.CompiledPage.HtmlContent,
                StyleContent = compilerResult.CompiledPage.StyleContent,
                References   = compilerResult.CompiledPage.References
            };

            // Add an event log entry to the database.

            if (addEventLogItem)
            {
                var eventItem = Request.CreateEvent();
                eventItem.ObjectType = ObjectType.Page;
                eventItem.ObjectId   = pageLayers.ContentPage.Id;
                eventItem.Project    = result.Portal.Project;
                eventItem.Contact    = contact;
                eventItem.AnonymId   = result.AnonymId;
                eventItem.CustomUri  = actionLink?.CustomUri;
                await _logManager.LogAsync(eventItem, portal.Owners, cancellationToken);

                result.Event = new EngineEventViewModel {
                    Id = eventItem.Id
                };
            }

            Response.SetAnonymId(result.AnonymId, cookiePath);

            return(result);
        }