/// <summary> /// Creates the user. /// </summary> /// <param name="user">The user.</param> /// <param name="password">The password.</param> /// <param name="email">The email.</param> /// <returns></returns> /// <exception cref="Exception"></exception> public User CreateUser(string user, string password, string email) { using (var db = new WeSketchDataContext()) { if (db.Users.Any(existingUser => existingUser.UserName == user)) { throw new Exception($"User {user} already exists."); } byte[] salt = GetSalt(); var userId = Guid.NewGuid(); var boardId = Guid.NewGuid(); var newUser = new User() { UserID = userId, UserName = user, Email = email, Password = GetComputedHash(password, salt), SeaSalt = Convert.ToBase64String(salt), Disabled = false, UserBoard = new UserBoard() { UserID = userId, BoardID = boardId, BoardOwner = true, CanSketch = true } }; db.Users.InsertOnSubmit(newUser); db.SubmitChanges(); return(db.Users.Single(usr => usr.UserName == user)); } }
/// <summary> /// Sends the strokes to the specieied user. /// </summary> /// <param name="serializedStrokes">The serialized strokes.</param> /// <param name="userId">The user identifier.</param> public void SendStrokesToUser(string user, string serializedStrokes) { using (var db = new WeSketchDataContext()) { var receiver = db.Users.Single(usr => usr.UserName == user); Clients.Group(receiver.UserID.ToString()).ReceiveStrokes(serializedStrokes); } }
/// <summary> /// Notifies the specified user that they have been kicked from the board. /// </summary> /// <param name="userName">User name of the user to kick from the board.</param> /// <param name="boardId">The board identifier that the user is being kicked from.</param> public void KickUserFromBoard(string userName, Guid boardId) { using (var db = new WeSketchDataContext()) { var user = db.Users.Single(usr => usr.UserName == userName); Clients.Group(user.UserID.ToString()).KickedFromBoard(boardId); } }
/// <summary> /// Sends the connected users to the specified user. /// </summary> /// <param name="user">The user to send the users to.</param> /// <param name="users">The users.</param> public void SendConnectedUsersToUser(string user, string users) { using (var db = new WeSketchDataContext()) { var receiver = db.Users.Single(usr => usr.UserName == user); Clients.Group(receiver.UserID.ToString()).ReceiveConnectedUsers(users); } }
/// <summary> /// After a user joins a board they request strokes from a board. /// </summary> /// <param name="user">The user identifier.</param> /// <param name="boardId">The board identifier.</param> public void RequestStrokes(string user, Guid boardId) { using (var db = new WeSketchDataContext()) { var board = db.UserBoards.Single(brd => brd.BoardID == boardId && brd.BoardOwner); Clients.Group(board.UserID.ToString()).ReceiveStrokeRequest(user); } }
/// <summary> /// Remove user from board group /// </summary> /// <param name="userName"></param> /// <param name="boardId"></param> public void RemoveFromGroups(string userName, Guid boardId) { using (var db = new WeSketchDataContext()) { var user = db.Users.Single(usr => usr.UserName == userName); Groups.Remove(Context.ConnectionId, user.UserID.ToString()); } Groups.Remove(Context.ConnectionId, boardId.ToString()); }
/// <summary> /// After a user joins a board they request the connected users from a board. /// </summary> /// <param name="user">The user identifier.</param> /// <param name="boardId">The board identifier.</param> public void RequestConnectedUsers(string user, Guid boardId) { using (var db = new WeSketchDataContext()) { var board = db.UserBoards.Single(brd => brd.BoardID == boardId && brd.BoardOwner); var receiver = db.Users.Single(usr => usr.UserName == user); Clients.Group(board.UserID.ToString()).ReceiveConnectedUsersRequest(user); } }
/// <summary>RequestConnectedUsers /// Joins the user to the board group. This allows the userto receive strokes sent to the group. /// </summary> /// <param name="userName">Name of the user.</param> /// <param name="color">The color currently assigned to the user.</param> /// <param name="boardId">The board identifier.</param> public void JoinBoardGroup(string userName, string color, Guid boardId) { Groups.Add(Context.ConnectionId, boardId.ToString()); using (var db = new WeSketchDataContext()) { var user = db.Users.Single(usr => usr.UserName == userName); Clients.Group(boardId.ToString()).UserJoinedBoard(JsonConvert.SerializeObject(new ConnectedUser() { UserName = userName, Color = color, Owner = boardId == user.UserBoard.BoardID })); } }
/// <summary> /// Leaves the board group. /// </summary> /// <param name="userName">Name of the user.</param> /// <param name="boardId">The board identifier.</param> public void LeaveBoardGroup(string userName, Guid boardId, string color) { Groups.Remove(Context.ConnectionId, boardId.ToString()); using (var db = new WeSketchDataContext()) { var user = db.Users.Single(usr => usr.UserName == userName); Groups.Add(Context.ConnectionId, user.UserBoard.BoardID.ToString()); if (boardId != user.UserBoard.BoardID) { Clients.Group(user.UserID.ToString()).UserBoardSetToDefault(user.UserBoard.BoardID, true); } Clients.Group(user.UserBoard.BoardID.ToString()).UserJoinedBoard(JsonConvert.SerializeObject(new ConnectedUser() { UserName = userName, Color = color, Owner = true })); } Clients.Group(boardId.ToString()).UserLeftBoard(userName); }
/// <summary> /// Logins the specified user. /// </summary> /// <param name="user">The user.</param> /// <param name="password">The password.</param> /// <returns></returns> public User Login(string user, string password) { string errorMessage = "Invalid credentials"; using (var db = new WeSketchDataContext()) { db.DeferredLoadingEnabled = false; var existingUser = db.Users.SingleOrDefault(eUser => eUser.UserName == user); if (existingUser == null) { db.SubmitChanges(); throw new Exception(errorMessage); } existingUser.LastLoginAttempt = DateTime.Now; HashAlgorithm algorithm = new SHA256Managed(); if (password == string.Empty) { throw new Exception(errorMessage); } byte[] attemptBytes = GetSeasonedPasswordBytes(password, Convert.FromBase64String(existingUser.SeaSalt), Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings["pepper"])); byte[] attemptHash = algorithm.ComputeHash(attemptBytes); byte[] existingHash = Convert.FromBase64String(existingUser.Password); if (!attemptHash.SequenceEqual(existingHash)) { db.SubmitChanges(); throw new Exception(errorMessage); } existingUser.LastLogin = DateTime.Now; db.SubmitChanges(); existingUser.UserBoard = db.UserBoards.Single(brd => brd.UserID == existingUser.UserID); return(existingUser); } }