[Back]
// // DotNetNuke - http://www.dotnetnuke.com // Copyright (c) 2002-2009 // by DotNetNuke Corporation // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated // documentation files (the "Software"), to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and // to permit persons to whom the Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial portions // of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // Based on // Silverlight2Chat // Copyright (c) 2009 // by Junnark Vicencio // // The Code Project Open License (CPOL) 1.02 // http://www.codeproject.com/info/cpol10.aspx using System.Web.Services; using System.Web.Script.Services; using System; using DotNetNuke.Entities.Users; using System.Linq; using System.Collections.Generic; using DotNetNuke.Services.Exceptions; using System.Security.Cryptography; using System.Text; using Microsoft.VisualBasic; namespace DotNetNuke.Modules.DNNSilverlightChat { [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService()] public class WebService : System.Web.Services.WebService { #region InsertMessage [WebMethod(Description = "InsertMessage")] public void InsertMessage(int PortalID, int ModuleId, int UserID, string Password, int? toUserID, string messageText, string color) { if (IsValidUser(PortalID, ModuleId, UserID, Password)) { DNNSilverlightChat_Message message = new DNNSilverlightChat_Message(); message.ModuleID = ModuleId; message.UserID = UserID; message.ToUserID = toUserID; message.Text = Strings.Left(messageText, 2000); message.Color = color; message.TimeStamp = DateTime.Now; DNNSilverlightChatDALDataContext db = new DNNSilverlightChatDALDataContext(); db.DNNSilverlightChat_Messages.InsertOnSubmit(message); try { db.SubmitChanges(); } catch (Exception ex) { Exceptions.LogException(ex); throw; } // Add the message to the cache List<MessageContract> messageContracts = GetCurrentMessagesFromCache(ModuleId); List<DNNChatUser> colDNNChatUser = GetCurrentUsersFromCache(ModuleId); MessageContract InsertMessageContract = new MessageContract(); InsertMessageContract.MessageID = message.MessageID; InsertMessageContract.Text = message.Text; InsertMessageContract.UserName = colDNNChatUser.Where(x => x.UserID == message.UserID).FirstOrDefault().UserName; InsertMessageContract.Color = message.Color; InsertMessageContract.TimeStamp = message.TimeStamp; messageContracts.Add(InsertMessageContract); // Remove messages that are more than 30 seconds old var MessagesToDelete = from m in messageContracts where m.TimeStamp < DateTime.Now.AddSeconds(-30) select m; foreach (var objMessage in MessagesToDelete) { messageContracts.Remove(objMessage); } } } #endregion #region GetMessages [WebMethod(Description = "GetMessages")] public List<MessageContract> GetMessages(int PortalID, int ModuleId, int UserID, string Password, int messageID, DateTime timeUserJoined) { List<MessageContract> messageContracts = new List<MessageContract>(); if (IsValidUser(PortalID, ModuleId, UserID, Password)) { // Get all messages that were not sent by the current user List<MessageContract> MessagesFromCache = GetCurrentMessagesFromCache(ModuleId); string strUsername = UserController.GetUser(PortalID, UserID, false).DisplayName; var messages = (from m in MessagesFromCache where m.MessageID > messageID && m.TimeStamp > DateTime.Now.AddSeconds(-31) && m.UserName != strUsername orderby m.MessageID ascending select new { m.MessageID, m.Text, m.UserName, m.Color }); foreach (var message in messages.ToList()) { MessageContract messageContract = new MessageContract(); messageContract.MessageID = message.MessageID; messageContract.Text = message.Text; messageContract.UserName = message.UserName; messageContract.Color = message.Color; messageContracts.Add(messageContract); } } return messageContracts; } #endregion #region GetUsers [WebMethod(Description = "GetUsers")] public List<DNNChatLoggedInUsers> GetUsers(int PortalID, int ModuleId, int UserID, string Password) { List<DNNChatLoggedInUsers> colDNNChatLoggedInUsers = new List<DNNChatLoggedInUsers>(); if (IsValidUser(PortalID, ModuleId, UserID, Password)) { List<DNNChatUser> colDNNChatUser = GetCurrentUsersFromCache(ModuleId); // Get the current user and update their last Message value var ChatUser = (from DNNChatUsers in colDNNChatUser where DNNChatUsers.UserID == UserID select DNNChatUsers).FirstOrDefault(); if (ChatUser != null) { ChatUser.LastMessage = DateTime.Now; } // Log out any users who have not been active var CACHEUsersToLogOut = from DNNChatUsers in colDNNChatUser where DNNChatUsers.LastMessage < DateTime.Now.AddMinutes(-1) select DNNChatUsers; foreach (var InactiveUser in CACHEUsersToLogOut) { colDNNChatUser.Remove(InactiveUser); } // Return a list of the users as a list of DNNChatLoggedInUserss // get all logged in users to this room (Get from Cache) var loggedInUsers = from objDNNChatUser in colDNNChatUser orderby objDNNChatUser.UserName ascending group objDNNChatUser by objDNNChatUser.UserName into ChatUsers select new { ChatUsers.Key }; foreach (var loggedInUser in loggedInUsers) { DNNChatLoggedInUsers DNNChatLoggedInUsers = new DNNChatLoggedInUsers(); DNNChatLoggedInUsers.UserName = loggedInUser.Key; // Get user email and convert to gravatar url var loggedInUserId = (from objDnnChatUser in colDNNChatUser where objDnnChatUser.UserName == loggedInUser.Key select objDnnChatUser.UserID).FirstOrDefault(); if (loggedInUserId != null) { DNNChatLoggedInUsers.ImageUrl = GetImageUrl(PortalID, loggedInUserId); } colDNNChatLoggedInUsers.Add(DNNChatLoggedInUsers); } } return colDNNChatLoggedInUsers; } #endregion #region LogOutUser [WebMethod(Description = "LogOutUser")] public void LogOutUser(int PortalID, int ModuleId, int UserID, string Password, int InactiveUser) { if (IsValidUser(PortalID, ModuleId, UserID, Password)) { List<DNNChatUser> colDNNChatUser = GetCurrentUsersFromCache(ModuleId); // Log out user var CACHEUserToLogOut = (from DNNChatUsers in colDNNChatUser where DNNChatUsers.UserID == InactiveUser select DNNChatUsers).FirstOrDefault(); colDNNChatUser.Remove(CACHEUserToLogOut); DNNSilverlightChatDALDataContext db = new DNNSilverlightChatDALDataContext(); // insert user "left the room" text DNNSilverlightChat_Message message = new DNNSilverlightChat_Message(); message.ModuleID = ModuleId; message.UserID = InactiveUser; message.ToUserID = null; message.Text = UserController.GetUser(PortalID, InactiveUser, false).DisplayName + " left the room."; message.Color = "Gray"; message.TimeStamp = DateTime.Now; db.DNNSilverlightChat_Messages.InsertOnSubmit(message); db.SubmitChanges(); } } #endregion #region IsValidUser private bool IsValidUser(int PortalID, int ModuleId, int UserID, string Password) { bool boolIsValidUser = false; List<DNNChatUser> colDNNChatUser = GetCurrentUsersFromCache(ModuleId); // let's check if this authenticated user exists DNNChatUser Chatuser = (from objDNNChatUser in colDNNChatUser where objDNNChatUser.UserID == UserID where objDNNChatUser.Password == Password select objDNNChatUser).FirstOrDefault(); // if user does not exist table if (Chatuser == null) { IWebXAMLAuthendicationHeader objIWebXAMLAuthendicationHeader = new IWebXAMLAuthendicationHeader(); objIWebXAMLAuthendicationHeader.PortalID = PortalID; objIWebXAMLAuthendicationHeader.UserID = UserID; objIWebXAMLAuthendicationHeader.Password = Password; objIWebXAMLAuthendicationHeader.ModuleId = ModuleId; IWebXAMLAuthendication objIWebXAMLAuthendication = new IWebXAMLAuthendication(objIWebXAMLAuthendicationHeader); if (!(objIWebXAMLAuthendication.IsUserValid())) { boolIsValidUser = false; } else { boolIsValidUser = true; } // If user is valid add them to the CACHE if (boolIsValidUser) { // Remove all instances that may be in CACHE var CACHEUserInstanceToLogOut = from DNNChatUsers in colDNNChatUser where DNNChatUsers.UserID == UserID select DNNChatUsers; foreach (var InactiveUser in CACHEUserInstanceToLogOut) { colDNNChatUser.Remove(InactiveUser); } // Add the user to Cache DNNChatUser loggedInUser = new DNNChatUser(); loggedInUser.UserID = UserID; loggedInUser.LastMessage = DateTime.Now; loggedInUser.UserName = UserController.GetUser(PortalID, UserID, false).DisplayName; loggedInUser.Password = Password; // Add the user to the cache colDNNChatUser.Add(loggedInUser); } } else { // The user is valid and already in the CACHE boolIsValidUser = true; } return boolIsValidUser; } #endregion #region GetCurrentUsersFromCache private static List<DNNChatUser> GetCurrentUsersFromCache(int ModuleId) { string key = String.Format("{0}_DNNChatUser", ModuleId.ToString()); List<DNNChatUser> colDNNChatUser; if (!CacheHelper.Get(key, out colDNNChatUser)) { colDNNChatUser = new List<DNNChatUser>(); CacheHelper.Add(colDNNChatUser, key); } return colDNNChatUser; } #endregion #region GetCurrentMessagesFromCache private static List<MessageContract> GetCurrentMessagesFromCache(int ModuleId) { string key = String.Format("{0}_DNNChatMessages", ModuleId.ToString()); List<MessageContract> colDNNChatMessages; if (!CacheHelper.Get(key, out colDNNChatMessages)) { colDNNChatMessages = new List<MessageContract>(); CacheHelper.Add(colDNNChatMessages, key); } return colDNNChatMessages; } #endregion #region GetImageUrl private static string GetImageUrl(int PortalID, int UserID) { var dnnUser = DotNetNuke.Entities.Users.UserController. GetUser(PortalID, UserID, true); string imageUrl = "http://www.gravatar.com/avatar/"; if (!string.IsNullOrEmpty(dnnUser.Email)) { // build up image url, including MD5 hash for supplied email: MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); UTF8Encoding encoder = new UTF8Encoding(); MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider(); byte[] hashedBytes = md5Hasher.ComputeHash (encoder.GetBytes(dnnUser.Email.ToLower())); StringBuilder sb = new StringBuilder(hashedBytes.Length * 2); for (int i = 0; i < hashedBytes.Length; i++) { sb.Append(hashedBytes[i].ToString("X2")); } // output parameters: imageUrl += sb.ToString().ToLower(); imageUrl += "?s=40"; imageUrl += "&d=wavatar"; } return imageUrl; } #endregion } #region DNNChatUser public class DNNChatUser { public int UserID { get; set; } public string UserName { get; set; } public System.DateTime LastMessage { get; set; } public string Password { get; set; } //public string ImageUrl { get; set; } } #endregion #region DNNChatLoggedInUsers [Serializable] public class DNNChatLoggedInUsers { public string UserName { get; set; } public string ImageUrl { get; set; } } #endregion #region MessageContract [Serializable] public class MessageContract { public int MessageID { get; set; } public string Text { get; set; } public string UserName { get; set; } public string Color { get; set; } public DateTime TimeStamp { get; set; } } #endregion }