/// <summary> /// Inserts a chat message. /// </summary> /// <param name="chatRoom">The chat room which contains the chat message.</param> /// <param name="chatMessage">The chat message to add.</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> protected virtual async Task LogMessageAsync(ChatRoomInfo chatRoom, ChatMessageInfo chatMessage, CancellationToken cancellationToken) { ThrowIfDisposed(); var logManager = GetLogManager(); if (chatRoom == null) { throw new ArgumentNullException("chatRoom"); } if (chatMessage == null) { throw new ArgumentNullException("chatMessage"); } if (chatMessage.From == null) { throw new InvalidOperationException("The user 'from' is unspecified."); } if (chatMessage.To == null) { throw new InvalidOperationException("The user 'to' is unspecified."); } if (chatMessage.From.Admin) { await logManager.LogAsync(new EventItem { AnonymId = GuidUtility.NewSequentialGuid(), ObjectType = ObjectType.Message, ObjectId = chatRoom.PageId, Contact = chatMessage.From.ContactId != null ? new AccountItem { Id = (int)chatMessage.From.ContactId } : null, Project = chatRoom.ProjectId != null ? new UniqueItem { Id = (int)chatRoom.ProjectId } : null, ClientId = chatMessage.To.IPAddress, CustomUri = chatMessage.To.NickName + " >>", Message = chatMessage.Message }, chatRoom.Users.Values, cancellationToken); } if (chatMessage.To.Admin) { await logManager.LogAsync(new EventItem { AnonymId = GuidUtility.NewSequentialGuid(), ObjectType = ObjectType.Message, ObjectId = chatRoom.PageId, Contact = chatMessage.From.ContactId != null ? new AccountItem { Id = (int)chatMessage.From.ContactId } : null, Project = chatRoom.ProjectId != null ? new UniqueItem { Id = (int)chatRoom.ProjectId } : null, ClientId = chatMessage.From.IPAddress, CustomUri = "<< " + chatMessage.From.NickName, Message = chatMessage.Message }, chatRoom.Users.Values, cancellationToken); } }
/// <summary> /// Called by the workflow runtime to execute an activity. /// </summary> /// <param name="context">The <see cref="ActionActivityContext"/> to associate with this activity and execution.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="ActionActivityResult"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state. /// </returns> public Task <ActionActivityResult> ExecuteAsync(ActionActivityContext context, CancellationToken cancellationToken) { if (!context.ContactExists) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Forbidden))); } if (context.ContactState == ObjectState.Deleted) { return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Failed))); } if ((context.AuthTicket == null) || (context.Contact.Id != context.AuthTicket.Id)) { context.AnonymId = GuidUtility.NewSequentialGuid(); } context.AuthTicket = AuthUtility.Create(context.Contact); return(Task.FromResult(context.CreateResult(ActionActivityStatusCode.Success))); }
/// <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); }