private static void ClearConnectedClients(IJabbrRepository repository) { try { repository.RemoveAllClients(); repository.CommitChanges(); } catch (Exception ex) { Elmah.ErrorLog.GetDefault(null).Log(new Error(ex)); } }
private static void ClearConnectedClients(IJabbrRepository repository) { try { foreach (var u in repository.Users) { u.Status = (int)UserStatus.Offline; } repository.RemoveAllClients(); repository.CommitChanges(); } catch (Exception ex) { Elmah.ErrorLog.GetDefault(null).Log(new Error(ex)); } }
public void SetInviteCode(ChatUser user, ChatRoom room, string inviteCode) { EnsureOwner(user, room); if (!room.Private) { throw new InvalidOperationException("Only private rooms can have invite codes"); } // Set the invite code and save room.InviteCode = inviteCode; _repository.CommitChanges(); }
public async Task <IActionResult> ChangeUsername(ChangeUsernameViewModel model) { if (!User.Identity.IsAuthenticated) { return(View(HttpStatusCode.Forbidden)); } // HttpContextAccessor DI works when Singelton (Scoped injects null) var id = _context.HttpContext.User.GetUserId(); ChatUser user = _repository.GetUserById(id); string oldUsername = user.Name; //user.UserName try { if (ModelState.IsValid) { var result = await _signInManager.CheckPasswordSignInAsync(user, model.password, false); if (result.Succeeded) { user.UserName = model.username; user.Name = model.username; _repository.CommitChanges(); // _notificationService.OnUserNameChanged(user, oldUsername, model.username); return(RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangeUsernameSuccess })); } else { return(new RedirectResult(Url.Action("Index", new { Message = ManageMessageId.WrongPassword }) + "#changeUsername")); } } } catch (Exception ex) { return(RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error })); } return(new RedirectResult(Url.Action("Index", new { Message = ManageMessageId.ErrorChangeUsername }) + "#changeUsername")); }
private ChatUser AddUser(string userName, string providerName, string identity, string email) { if (!IsValidUserName(userName)) { throw new InvalidOperationException(String.Format("'{0}' is not a valid user name.", userName)); } EnsureProviderAndIdentityAvailable(providerName, identity); // This method is used in the auth workflow. If the username is taken it will add a number // to the user name. if (UserExists(userName)) { var usersWithNameLikeMine = _repository.Users.Count(u => u.Name.StartsWith(userName)); userName += usersWithNameLikeMine; } var user = new ChatUser { Name = userName, Status = (int)UserStatus.Active, Hash = email.ToMD5(), Id = Guid.NewGuid().ToString("d"), LastActivity = DateTime.UtcNow, IsAdmin = IsFirstUser() }; var chatUserIdentity = new ChatUserIdentity { User = user, Email = email, Identity = identity, ProviderName = providerName }; _repository.Add(user); _repository.Add(chatUserIdentity); _repository.CommitChanges(); return(user); }
private void CheckUserStatus(ILogger logger, IJabbrRepository repo) { var inactiveUsers = new List <ChatUser>(); IQueryable <ChatUser> users = repo.GetOnlineUsers().Where(u => SqlFunctions.DateDiff("mi", u.LastActivity, DateTime.UtcNow) > 5); foreach (var user in users.ToList()) { user.Status = (int)UserStatus.Inactive; inactiveUsers.Add(user); } if (inactiveUsers.Count > 0) { PerformRoomAction(inactiveUsers, async roomGroup => { await _hubContext.Clients.Group(roomGroup.Room.Name).markInactive(roomGroup.Users); }); repo.CommitChanges(); } }
private void UpdatePresence(ILogger logger, IJabbrRepository repo) { // Get all connections on this node and update the activity foreach (var connection in _heartbeat.GetConnections()) { if (!connection.IsAlive) { continue; } ChatClient client = repo.GetClientById(connection.ConnectionId); if (client != null) { client.LastActivity = DateTimeOffset.UtcNow; } else { EnsureClientConnected(logger, repo, connection); } } repo.CommitChanges(); }
public void Join(bool reconnecting) { // Get the client state var userId = Context.User.GetUserId(); // Try to get the user from the client state ChatUser user = _repository.GetUserById(userId); if (!reconnecting) { // Update some user values _service.UpdateActivity(user, Context.ConnectionId, UserAgent); _repository.CommitChanges(); } ClientState clientState = GetClientState(); OnUserInitialize(clientState, user, reconnecting); }
private void RemoveOfflineUsers(ILogger logger, IJabbrRepository repo) { var offlineUsers = new List<ChatUser>(); IQueryable<ChatUser> users = repo.GetOnlineUsers(); foreach (var user in users.ToList()) { if (user.ConnectedClients.Count == 0) { logger.Log("{0} has no clients. Marking as offline", user.Name); // Fix users that are marked as inactive but have no clients user.Status = (int)UserStatus.Offline; offlineUsers.Add(user); } } if (offlineUsers.Count > 0) { PerformRoomAction(offlineUsers, async roomGroup => { foreach (var user in roomGroup.Users) { await _hubContext.Clients.Group(roomGroup.Room.Name).leave(user, roomGroup.Room.Name); } }); repo.CommitChanges(); } }
// This is an uber hack to make sure the db is in sync with SignalR private void EnsureClientConnected(ILogger logger, IJabbrRepository repo, ITrackingConnection connection) { var contextField = connection.GetType().GetField("_context", BindingFlags.NonPublic | BindingFlags.Instance); if (contextField == null) { return; } var context = contextField.GetValue(connection) as HostContext; if (context == null) { return; } string connectionData = context.Request.QueryString["connectionData"]; if (String.IsNullOrEmpty(connectionData)) { return; } var hubs = JsonConvert.DeserializeObject<HubConnectionData[]>(connectionData); if (hubs.Length != 1) { return; } // We only care about the chat hub if (!hubs[0].Name.Equals("chat", StringComparison.OrdinalIgnoreCase)) { return; } logger.Log("Connection {0} exists but isn't tracked.", connection.ConnectionId); string userId = context.Request.User.GetUserId(); ChatUser user = repo.GetUserById(userId); if (user == null) { logger.Log("Unable to find user with id {0}", userId); return; } var client = new ChatClient { Id = connection.ConnectionId, User = user, UserAgent = context.Request.Headers["User-Agent"], LastActivity = DateTimeOffset.UtcNow, LastClientActivity = user.LastActivity }; repo.Add(client); repo.CommitChanges(); }
public AccountModule(IApplicationSettings applicationSettings, IAuthenticationTokenService authenticationTokenService, IMembershipService membershipService, IJabbrRepository repository, IAuthenticationService authService, IChatNotificationService notificationService) : base("/account") { Get["/"] = _ => { if (Context.CurrentUser == null) { return HttpStatusCode.Forbidden; } ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); return GetProfileView(authService, user); }; Get["/login"] = _ => { if (Context.CurrentUser != null) { return Response.AsRedirect("~/"); } return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; }; Post["/login"] = param => { if (Context.CurrentUser != null) { return Response.AsRedirect("~/"); } string username = Request.Form.username; string password = Request.Form.password; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(password)) { this.AddValidationError("password", "Password is required"); } try { if (ModelValidationResult.IsValid) { ChatUser user = membershipService.AuthenticateUser(username, password); return this.CompleteLogin(authenticationTokenService, user); } else { return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; } } catch { this.AddValidationError("_FORM", "Login failed. Check your username/password."); return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; } }; Post["/logout"] = _ => { if (Context.CurrentUser == null) { return HttpStatusCode.Forbidden; } var response = Response.AsJson(new { success = true }); response.AddCookie(new NancyCookie(Constants.UserTokenCookie, null) { Expires = DateTime.Now.AddDays(-1) }); return response; }; Get["/register"] = _ => { if (Context.CurrentUser != null) { return Response.AsRedirect("~/"); } return View["register"]; }; Post["/create"] = _ => { if (Context.CurrentUser != null) { return Response.AsRedirect("~/"); } string username = Request.Form.username; string email = Request.Form.email; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(email)) { this.AddValidationError("email", "Email is required"); } ValidatePassword(password, confirmPassword); try { if (ModelValidationResult.IsValid) { ChatUser user = membershipService.AddUser(username, email, password); return this.CompleteLogin(authenticationTokenService, user); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return View["register"]; }; Post["/unlink"] = param => { if (Context.CurrentUser == null) { return HttpStatusCode.Forbidden; } string provider = Request.Form.provider; ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); if (user.Identities.Count == 1 && !user.HasUserNameAndPasswordCredentials()) { this.AddAlertMessage("error", "You cannot unlink this account because you would lose your ability to login."); return Response.AsRedirect("~/account/#identityProviders"); } var identity = user.Identities.FirstOrDefault(i => i.ProviderName == provider); if (identity != null) { repository.Remove(identity); this.AddAlertMessage("success", String.Format("Successfully unlinked {0} account.", provider)); return Response.AsRedirect("~/account/#identityProviders"); } return HttpStatusCode.BadRequest; }; Post["/newpassword"] = _ => { if (Context.CurrentUser == null) { return HttpStatusCode.Forbidden; } string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); try { if (ModelValidationResult.IsValid) { membershipService.SetUserPassword(user, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { this.AddAlertMessage("success", "Successfully added a password."); return Response.AsRedirect("~/account/#changePassword"); } return GetProfileView(authService, user); }; Post["/changepassword"] = _ => { if (Context.CurrentUser == null) { return HttpStatusCode.Forbidden; } string oldPassword = Request.Form.oldPassword; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(oldPassword)) { this.AddValidationError("oldPassword", "Old password is required"); } ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserPassword(user, oldPassword, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { this.AddAlertMessage("success", "Successfully changed your password."); return Response.AsRedirect("~/account/#changePassword"); } return GetProfileView(authService, user); }; Post["/changeusername"] = _ => { if (Context.CurrentUser == null) { return HttpStatusCode.Forbidden; } string username = Request.Form.username; string confirmUsername = Request.Form.confirmUsername; ValidateUsername(username, confirmUsername); ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); string oldUsername = user.Name; try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserName(user, username); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { notificationService.OnUserNameChanged(user, oldUsername, username); this.AddAlertMessage("success", "Successfully changed your username."); return Response.AsRedirect("~/account/#changeUsername"); } return GetProfileView(authService, user); }; }
public void SetInviteCode(ChatUser user, ChatRoom room, string inviteCode) { EnsureOwnerOrAdmin(user, room); if (!room.Private) { throw new HubException(LanguageResources.InviteCode_PrivateRoomRequired); } // Set the invite code and save room.InviteCode = inviteCode; _repository.CommitChanges(); }
public AccountModule(ApplicationSettings applicationSettings, IMembershipService membershipService, IJabbrRepository repository, IAuthenticationService authService, IChatNotificationService notificationService, IUserAuthenticator authenticator) : base("/account") { Get["/"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } ChatUser user = repository.GetUserById(Principal.GetUserId()); return GetProfileView(authService, user); }; Get["/login"] = _ => { if (IsAuthenticated) { return Response.AsRedirect("~/"); } return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; }; Post["/login"] = param => { if (IsAuthenticated) { return Response.AsRedirect("~/"); } string username = Request.Form.username; string password = Request.Form.password; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(password)) { this.AddValidationError("password", "Password is required"); } try { if (ModelValidationResult.IsValid) { IList<Claim> claims; if (authenticator.TryAuthenticateUser(username, password, out claims)) { return this.SignIn(claims); } } } catch { // Swallow the exception } this.AddValidationError("_FORM", "Login failed. Check your username/password."); return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; }; Post["/logout"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } var response = Response.AsJson(new { success = true }); this.SignOut(); return response; }; Get["/register"] = _ => { if (IsAuthenticated) { return Response.AsRedirect("~/"); } bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return HttpStatusCode.NotFound; } ViewBag.requirePassword = requirePassword; return View["register"]; }; Post["/create"] = _ => { bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return HttpStatusCode.NotFound; } if (IsAuthenticated) { return Response.AsRedirect("~/"); } ViewBag.requirePassword = requirePassword; string username = Request.Form.username; string email = Request.Form.email; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(email)) { this.AddValidationError("email", "Email is required"); } try { if (requirePassword) { ValidatePassword(password, confirmPassword); } if (ModelValidationResult.IsValid) { if (requirePassword) { ChatUser user = membershipService.AddUser(username, email, password); return this.SignIn(user); } else { // Add the required claims to this identity var identity = Principal.Identity as ClaimsIdentity; if (!Principal.HasClaim(ClaimTypes.Name)) { identity.AddClaim(new Claim(ClaimTypes.Name, username)); } if (!Principal.HasClaim(ClaimTypes.Email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } return this.SignIn(Principal.Claims); } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return View["register"]; }; Post["/unlink"] = param => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string provider = Request.Form.provider; ChatUser user = repository.GetUserById(Principal.GetUserId()); if (user.Identities.Count == 1 && !user.HasUserNameAndPasswordCredentials()) { Request.AddAlertMessage("error", "You cannot unlink this account because you would lose your ability to login."); return Response.AsRedirect("~/account/#identityProviders"); } var identity = user.Identities.FirstOrDefault(i => i.ProviderName == provider); if (identity != null) { repository.Remove(identity); Request.AddAlertMessage("success", String.Format("Successfully unlinked {0} account.", provider)); return Response.AsRedirect("~/account/#identityProviders"); } return HttpStatusCode.BadRequest; }; Post["/newpassword"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.SetUserPassword(user, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", "Successfully added a password."); return Response.AsRedirect("~/account/#changePassword"); } return GetProfileView(authService, user); }; Post["/changepassword"] = _ => { if (!applicationSettings.AllowUserRegistration) { return HttpStatusCode.NotFound; } if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string oldPassword = Request.Form.oldPassword; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(oldPassword)) { this.AddValidationError("oldPassword", "Old password is required"); } ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserPassword(user, oldPassword, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", "Successfully changed your password."); return Response.AsRedirect("~/account/#changePassword"); } return GetProfileView(authService, user); }; Post["/changeusername"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string username = Request.Form.username; string confirmUsername = Request.Form.confirmUsername; ValidateUsername(username, confirmUsername); ChatUser user = repository.GetUserById(Principal.GetUserId()); string oldUsername = user.Name; try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserName(user, username); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { notificationService.OnUserNameChanged(user, oldUsername, username); Request.AddAlertMessage("success", "Successfully changed your username."); return Response.AsRedirect("~/account/#changeUsername"); } return GetProfileView(authService, user); }; }
private static void ClearConnectedClients(IJabbrRepository repository) { try { foreach (var u in repository.Users) { if (u.IsAfk) { u.Status = (int)UserStatus.Offline; } } repository.RemoveAllClients(); repository.CommitChanges(); } catch (Exception ex) { Elmah.ErrorLog.GetDefault(null).Log(new Error(ex)); } }
public AccountModule(ApplicationSettings applicationSettings, IMembershipService membershipService, IJabbrRepository repository, IAuthenticationService authService, IChatNotificationService notificationService, IUserAuthenticator authenticator, IEmailService emailService) : base("/account") { Get["/"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } ChatUser user = repository.GetUserById(Principal.GetUserId()); return GetProfileView(authService, user); }; Get["/login"] = _ => { if (IsAuthenticated) { return this.AsRedirectQueryStringOrDefault("~/"); } return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; }; Post["/login"] = param => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (IsAuthenticated) { return this.AsRedirectQueryStringOrDefault("~/"); } string username = Request.Form.username; string password = Request.Form.password; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", LanguageResources.Authentication_NameRequired); } if (String.IsNullOrEmpty(password)) { this.AddValidationError("password", LanguageResources.Authentication_PassRequired); } try { if (ModelValidationResult.IsValid) { IList<Claim> claims; if (authenticator.TryAuthenticateUser(username, password, out claims)) { return this.SignIn(claims); } } } catch { // Swallow the exception } this.AddValidationError("_FORM", LanguageResources.Authentication_GenericFailure); return View["login", GetLoginViewModel(applicationSettings, repository, authService)]; }; Post["/logout"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } var response = Response.AsJson(new { success = true }); this.SignOut(); return response; }; Get["/register"] = _ => { if (IsAuthenticated) { return this.AsRedirectQueryStringOrDefault("~/"); } bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return HttpStatusCode.NotFound; } ViewBag.requirePassword = requirePassword; return View["register"]; }; Post["/create"] = _ => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return HttpStatusCode.NotFound; } if (IsAuthenticated) { return this.AsRedirectQueryStringOrDefault("~/"); } ViewBag.requirePassword = requirePassword; string username = Request.Form.username; string email = Request.Form.email; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", LanguageResources.Authentication_NameRequired); } if (String.IsNullOrEmpty(email)) { this.AddValidationError("email", LanguageResources.Authentication_EmailRequired); } try { if (requirePassword) { ValidatePassword(password, confirmPassword); } if (ModelValidationResult.IsValid) { if (requirePassword) { ChatUser user = membershipService.AddUser(username, email, password); return this.SignIn(user); } else { // Add the required claims to this identity var identity = Principal.Identity as ClaimsIdentity; if (!Principal.HasClaim(ClaimTypes.Name)) { identity.AddClaim(new Claim(ClaimTypes.Name, username)); } if (!Principal.HasClaim(ClaimTypes.Email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } return this.SignIn(Principal.Claims); } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return View["register"]; }; Post["/unlink"] = param => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string provider = Request.Form.provider; ChatUser user = repository.GetUserById(Principal.GetUserId()); if (user.Identities.Count == 1 && !user.HasUserNameAndPasswordCredentials()) { Request.AddAlertMessage("error", LanguageResources.Account_UnlinkRequiresMultipleIdentities); return Response.AsRedirect("~/account/#identityProviders"); } var identity = user.Identities.FirstOrDefault(i => i.ProviderName == provider); if (identity != null) { repository.Remove(identity); Request.AddAlertMessage("success", String.Format(LanguageResources.Account_UnlinkCompleted, provider)); return Response.AsRedirect("~/account/#identityProviders"); } return HttpStatusCode.BadRequest; }; Post["/newpassword"] = _ => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.SetUserPassword(user, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", LanguageResources.Authentication_PassAddSuccess); return Response.AsRedirect("~/account/#changePassword"); } return GetProfileView(authService, user); }; Post["/changepassword"] = _ => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (!applicationSettings.AllowUserRegistration) { return HttpStatusCode.NotFound; } if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string oldPassword = Request.Form.oldPassword; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(oldPassword)) { this.AddValidationError("oldPassword", LanguageResources.Authentication_OldPasswordRequired); } ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserPassword(user, oldPassword, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", LanguageResources.Authentication_PassChangeSuccess); return Response.AsRedirect("~/account/#changePassword"); } return GetProfileView(authService, user); }; Post["/changeusername"] = _ => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } string username = Request.Form.username; string confirmUsername = Request.Form.confirmUsername; ValidateUsername(username, confirmUsername); ChatUser user = repository.GetUserById(Principal.GetUserId()); string oldUsername = user.Name; try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserName(user, username); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { notificationService.OnUserNameChanged(user, oldUsername, username); Request.AddAlertMessage("success", LanguageResources.Authentication_NameChangeCompleted); return Response.AsRedirect("~/account/#changeUsername"); } return GetProfileView(authService, user); }; Get["/requestresetpassword"] = _ => { if (IsAuthenticated) { return Response.AsRedirect("~/account/#changePassword"); } if (!Principal.Identity.IsAuthenticated && !applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return HttpStatusCode.NotFound; } return View["requestresetpassword"]; }; Post["/requestresetpassword"] = _ => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (IsAuthenticated) { return Response.AsRedirect("~/account/#changePassword"); } if (!Principal.Identity.IsAuthenticated && !applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return HttpStatusCode.NotFound; } string username = Request.Form.username; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", LanguageResources.Authentication_NameRequired); } try { if (ModelValidationResult.IsValid) { ChatUser user = repository.GetUserByName(username); if (user == null) { this.AddValidationError("username", String.Format(LanguageResources.Account_NoMatchingUser, username)); } else if (String.IsNullOrWhiteSpace(user.Email)) { this.AddValidationError("username", String.Format(LanguageResources.Account_NoEmailForUser, username)); } else { membershipService.RequestResetPassword(user, applicationSettings.RequestResetPasswordValidThroughInHours); repository.CommitChanges(); emailService.SendRequestResetPassword(user, this.Request.Url.SiteBase + "/account/resetpassword/"); return View["requestresetpasswordsuccess", username]; } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return View["requestresetpassword"]; }; Get["/resetpassword/{id}"] = parameters => { if (!applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return HttpStatusCode.NotFound; } string resetPasswordToken = parameters.id; string userName = membershipService.GetUserNameFromToken(resetPasswordToken); // Is the token not valid, maybe some character change? if (userName == null) { return View["resetpassworderror", LanguageResources.Account_ResetInvalidToken]; } else { ChatUser user = repository.GetUserByRequestResetPasswordId(userName, resetPasswordToken); // Is the token expired? if (user == null) { return View["resetpassworderror", LanguageResources.Account_ResetExpiredToken]; } else { return View["resetpassword", user.RequestPasswordResetId]; } } }; Post["/resetpassword/{id}"] = parameters => { if (!HasValidCsrfTokenOrSecHeader) { return HttpStatusCode.Forbidden; } if (!applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return HttpStatusCode.NotFound; } string resetPasswordToken = parameters.id; string newPassword = Request.Form.password; string confirmNewPassword = Request.Form.confirmPassword; ValidatePassword(newPassword, confirmNewPassword); try { if (ModelValidationResult.IsValid) { string userName = membershipService.GetUserNameFromToken(resetPasswordToken); ChatUser user = repository.GetUserByRequestResetPasswordId(userName, resetPasswordToken); // Is the token expired? if (user == null) { return View["resetpassworderror", LanguageResources.Account_ResetExpiredToken]; } else { membershipService.ResetUserPassword(user, newPassword); repository.CommitChanges(); return View["resetpasswordsuccess"]; } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return View["resetpassword", resetPasswordToken]; }; }
public AccountModule(ApplicationSettings applicationSettings, IMembershipService membershipService, IJabbrRepository repository, IAuthenticationService authService, IChatNotificationService notificationService, IUserAuthenticator authenticator) : base("/account") { Get["/"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } ChatUser user = repository.GetUserById(Principal.GetUserId()); return(GetProfileView(authService, user)); }; Get["/login"] = _ => { if (IsAuthenticated) { return(Response.AsRedirect("~/")); } return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); }; Post["/login"] = param => { if (IsAuthenticated) { return(Response.AsRedirect("~/")); } string username = Request.Form.username; string password = Request.Form.password; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(password)) { this.AddValidationError("password", "Password is required"); } try { if (ModelValidationResult.IsValid) { IList <Claim> claims; if (authenticator.TryAuthenticateUser(username, password, out claims)) { return(this.SignIn(claims)); } } } catch { // Swallow the exception } this.AddValidationError("_FORM", "Login failed. Check your username/password."); return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); }; Post["/logout"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } var response = Response.AsJson(new { success = true }); this.SignOut(); return(response); }; Get["/register"] = _ => { if (IsAuthenticated) { return(Response.AsRedirect("~/")); } bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return(HttpStatusCode.NotFound); } ViewBag.requirePassword = requirePassword; return(View["register"]); }; Post["/create"] = _ => { bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return(HttpStatusCode.NotFound); } if (IsAuthenticated) { return(Response.AsRedirect("~/")); } ViewBag.requirePassword = requirePassword; string username = Request.Form.username; string email = Request.Form.email; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(email)) { this.AddValidationError("email", "Email is required"); } try { if (requirePassword) { ValidatePassword(password, confirmPassword); } if (ModelValidationResult.IsValid) { if (requirePassword) { ChatUser user = membershipService.AddUser(username, email, password); return(this.SignIn(user)); } else { // Add the required claims to this identity var identity = Principal.Identity as ClaimsIdentity; if (!Principal.HasClaim(ClaimTypes.Name)) { identity.AddClaim(new Claim(ClaimTypes.Name, username)); } if (!Principal.HasClaim(ClaimTypes.Email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } return(this.SignIn(Principal.Claims)); } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return(View["register"]); }; Post["/unlink"] = param => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string provider = Request.Form.provider; ChatUser user = repository.GetUserById(Principal.GetUserId()); if (user.Identities.Count == 1 && !user.HasUserNameAndPasswordCredentials()) { Request.AddAlertMessage("error", "You cannot unlink this account because you would lose your ability to login."); return(Response.AsRedirect("~/account/#identityProviders")); } var identity = user.Identities.FirstOrDefault(i => i.ProviderName == provider); if (identity != null) { repository.Remove(identity); Request.AddAlertMessage("success", String.Format("Successfully unlinked {0} account.", provider)); return(Response.AsRedirect("~/account/#identityProviders")); } return(HttpStatusCode.BadRequest); }; Post["/newpassword"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.SetUserPassword(user, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", "Successfully added a password."); return(Response.AsRedirect("~/account/#changePassword")); } return(GetProfileView(authService, user)); }; Post["/changepassword"] = _ => { if (!applicationSettings.AllowUserRegistration) { return(HttpStatusCode.NotFound); } if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string oldPassword = Request.Form.oldPassword; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(oldPassword)) { this.AddValidationError("oldPassword", "Old password is required"); } ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserPassword(user, oldPassword, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", "Successfully changed your password."); return(Response.AsRedirect("~/account/#changePassword")); } return(GetProfileView(authService, user)); }; Post["/changeusername"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string username = Request.Form.username; string confirmUsername = Request.Form.confirmUsername; ValidateUsername(username, confirmUsername); ChatUser user = repository.GetUserById(Principal.GetUserId()); string oldUsername = user.Name; try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserName(user, username); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { notificationService.OnUserNameChanged(user, oldUsername, username); Request.AddAlertMessage("success", "Successfully changed your username."); return(Response.AsRedirect("~/account/#changeUsername")); } return(GetProfileView(authService, user)); }; }
public NotificationsModule(IJabbrRepository repository, IChatService chatService, IChatNotificationService notificationService) : base("/notifications") { Get["/"] = _ => { if (!IsAuthenticated) { return Response.AsRedirect(String.Format("~/account/login?returnUrl={0}", HttpUtility.UrlEncode(Request.Path))); } var request = this.Bind<NotificationRequestModel>(); ChatUser user = repository.GetUserById(Principal.GetUserId()); int unreadCount = repository.GetUnreadNotificationsCount(user); IPagedList<NotificationViewModel> notifications = GetNotifications(repository, user, all: request.All, page: request.Page, roomName: request.Room); var viewModel = new NotificationsViewModel { ShowAll = request.All, UnreadCount = unreadCount, Notifications = notifications, DebugMode = (bool)Context.Items["_debugMode"], }; return View["index", viewModel]; }; Post["/markasread"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } int notificationId = Request.Form.notificationId; Notification notification = repository.GetNotificationById(notificationId); if (notification == null) { return HttpStatusCode.NotFound; } ChatUser user = repository.GetUserById(Principal.GetUserId()); if (notification.UserKey != user.Key) { return HttpStatusCode.Forbidden; } notification.Read = true; repository.CommitChanges(); notificationService.MessageReadStateChanged(user, notification.Message, notification); UpdateUnreadCountInChat(repository, notificationService, user); var response = Response.AsJson(new { success = true }); return response; }; Post["/markallasread"] = _ => { if (!IsAuthenticated) { return HttpStatusCode.Forbidden; } ChatUser user = repository.GetUserById(Principal.GetUserId()); IList<Notification> unReadNotifications = repository.GetNotificationsByUser(user).Unread().ToList(); if (!unReadNotifications.Any()) { return HttpStatusCode.NotFound; } foreach (var notification in unReadNotifications) { notification.Read = true; notificationService.MessageReadStateChanged(user, notification.Message, notification); } repository.CommitChanges(); UpdateUnreadCountInChat(repository, notificationService, user); var response = Response.AsJson(new { success = true }); return response; }; Get["/{key}"] = _ => { if (!IsAuthenticated) return Response.AsRedirect(String.Format("~/account/login?returnUrl={0}", HttpUtility.UrlEncode(Request.Path))); var notification = repository.GetNotificationById(_.key); if (notification == null) return HttpStatusCode.NotFound; var user = repository.GetUserById(Principal.GetUserId()); if (notification.UserKey != user.Key) return HttpStatusCode.Forbidden; var model = new { DebugMode = (bool)Context.Items["_debugMode"], Notification = notification }; return View["view", model]; }; }
public AccountModule(ApplicationSettings applicationSettings, IMembershipService membershipService, IJabbrRepository repository, IAuthenticationService authService, IChatNotificationService notificationService, IUserAuthenticator authenticator, IEmailService emailService) : base("/account") { Get["/"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } ChatUser user = repository.GetUserById(Principal.GetUserId()); return(GetProfileView(authService, user)); }; Get["/login"] = _ => { if (IsAuthenticated) { return(this.AsRedirectQueryStringOrDefault("~/")); } return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); }; Post["/login"] = param => { if (IsAuthenticated) { return(this.AsRedirectQueryStringOrDefault("~/")); } string username = Request.Form.username; string password = Request.Form.password; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", LanguageResources.Authentication_NameRequired); } if (String.IsNullOrEmpty(password)) { this.AddValidationError("password", LanguageResources.Authentication_PassRequired); } try { if (ModelValidationResult.IsValid) { IList <Claim> claims; if (authenticator.TryAuthenticateUser(username, password, out claims)) { return(this.SignIn(claims)); } } } catch { // Swallow the exception } this.AddValidationError("_FORM", LanguageResources.Authentication_GenericFailure); return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); }; Post["/logout"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } var response = Response.AsJson(new { success = true }); this.SignOut(); return(response); }; Get["/register"] = _ => { if (IsAuthenticated) { return(this.AsRedirectQueryStringOrDefault("~/")); } bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return(HttpStatusCode.NotFound); } ViewBag.requirePassword = requirePassword; return(View["register"]); }; Post["/create"] = _ => { bool requirePassword = !Principal.Identity.IsAuthenticated; if (requirePassword && !applicationSettings.AllowUserRegistration) { return(HttpStatusCode.NotFound); } if (IsAuthenticated) { return(this.AsRedirectQueryStringOrDefault("~/")); } ViewBag.requirePassword = requirePassword; string username = Request.Form.username; string email = Request.Form.email; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", LanguageResources.Authentication_NameRequired); } if (String.IsNullOrEmpty(email)) { this.AddValidationError("email", LanguageResources.Authentication_EmailRequired); } try { if (requirePassword) { ValidatePassword(password, confirmPassword); } if (ModelValidationResult.IsValid) { if (requirePassword) { ChatUser user = membershipService.AddUser(username, email, password); return(this.SignIn(user)); } else { // Add the required claims to this identity var identity = Principal.Identity as ClaimsIdentity; if (!Principal.HasClaim(ClaimTypes.Name)) { identity.AddClaim(new Claim(ClaimTypes.Name, username)); } if (!Principal.HasClaim(ClaimTypes.Email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } return(this.SignIn(Principal.Claims)); } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return(View["register"]); }; Post["/unlink"] = param => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string provider = Request.Form.provider; ChatUser user = repository.GetUserById(Principal.GetUserId()); if (user.Identities.Count == 1 && !user.HasUserNameAndPasswordCredentials()) { Request.AddAlertMessage("error", LanguageResources.Account_UnlinkRequiresMultipleIdentities); return(Response.AsRedirect("~/account/#identityProviders")); } var identity = user.Identities.FirstOrDefault(i => i.ProviderName == provider); if (identity != null) { repository.Remove(identity); Request.AddAlertMessage("success", String.Format(LanguageResources.Account_UnlinkCompleted, provider)); return(Response.AsRedirect("~/account/#identityProviders")); } return(HttpStatusCode.BadRequest); }; Post["/newpassword"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.SetUserPassword(user, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", LanguageResources.Authentication_PassAddSuccess); return(Response.AsRedirect("~/account/#changePassword")); } return(GetProfileView(authService, user)); }; Post["/changepassword"] = _ => { if (!applicationSettings.AllowUserRegistration) { return(HttpStatusCode.NotFound); } if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string oldPassword = Request.Form.oldPassword; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(oldPassword)) { this.AddValidationError("oldPassword", LanguageResources.Authentication_OldPasswordRequired); } ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Principal.GetUserId()); try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserPassword(user, oldPassword, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { Request.AddAlertMessage("success", LanguageResources.Authentication_PassChangeSuccess); return(Response.AsRedirect("~/account/#changePassword")); } return(GetProfileView(authService, user)); }; Post["/changeusername"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } string username = Request.Form.username; string confirmUsername = Request.Form.confirmUsername; ValidateUsername(username, confirmUsername); ChatUser user = repository.GetUserById(Principal.GetUserId()); string oldUsername = user.Name; try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserName(user, username); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { notificationService.OnUserNameChanged(user, oldUsername, username); Request.AddAlertMessage("success", LanguageResources.Authentication_NameChangeCompleted); return(Response.AsRedirect("~/account/#changeUsername")); } return(GetProfileView(authService, user)); }; Get["/requestresetpassword"] = _ => { if (IsAuthenticated) { return(Response.AsRedirect("~/account/#changePassword")); } if (!Principal.Identity.IsAuthenticated && !applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return(HttpStatusCode.NotFound); } return(View["requestresetpassword"]); }; Post["/requestresetpassword"] = _ => { if (IsAuthenticated) { return(Response.AsRedirect("~/account/#changePassword")); } if (!Principal.Identity.IsAuthenticated && !applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return(HttpStatusCode.NotFound); } string username = Request.Form.username; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", LanguageResources.Authentication_NameRequired); } try { if (ModelValidationResult.IsValid) { ChatUser user = repository.GetUserByName(username); if (user == null) { this.AddValidationError("username", String.Format(LanguageResources.Account_NoMatchingUser, username)); } else if (String.IsNullOrWhiteSpace(user.Email)) { this.AddValidationError("username", String.Format(LanguageResources.Account_NoEmailForUser, username)); } else { membershipService.RequestResetPassword(user, applicationSettings.RequestResetPasswordValidThroughInHours); repository.CommitChanges(); emailService.SendRequestResetPassword(user, this.Request.Url.SiteBase + "/account/resetpassword/"); return(View["requestresetpasswordsuccess", username]); } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return(View["requestresetpassword"]); }; Get["/resetpassword/{id}"] = parameters => { if (!applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return(HttpStatusCode.NotFound); } string resetPasswordToken = parameters.id; string userName = membershipService.GetUserNameFromToken(resetPasswordToken); // Is the token not valid, maybe some character change? if (userName == null) { return(View["resetpassworderror", LanguageResources.Account_ResetInvalidToken]); } else { ChatUser user = repository.GetUserByRequestResetPasswordId(userName, resetPasswordToken); // Is the token expired? if (user == null) { return(View["resetpassworderror", LanguageResources.Account_ResetExpiredToken]); } else { return(View["resetpassword", user.RequestPasswordResetId]); } } }; Post["/resetpassword/{id}"] = parameters => { if (!applicationSettings.AllowUserResetPassword || string.IsNullOrWhiteSpace(applicationSettings.EmailSender)) { return(HttpStatusCode.NotFound); } string resetPasswordToken = parameters.id; string newPassword = Request.Form.password; string confirmNewPassword = Request.Form.confirmPassword; ValidatePassword(newPassword, confirmNewPassword); try { if (ModelValidationResult.IsValid) { string userName = membershipService.GetUserNameFromToken(resetPasswordToken); ChatUser user = repository.GetUserByRequestResetPasswordId(userName, resetPasswordToken); // Is the token expired? if (user == null) { return(View["resetpassworderror", LanguageResources.Account_ResetExpiredToken]); } else { membershipService.ResetUserPassword(user, newPassword); repository.CommitChanges(); return(View["resetpasswordsuccess"]); } } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return(View["resetpassword", resetPasswordToken]); }; }
public void ResponseSignIn(CookieResponseSignInContext context) { var authResult = new AuthenticationResult { Success = true }; ChatUser loggedInUser = GetLoggedInUser(context); var principal = new ClaimsPrincipal(context.Identity); // Do nothing if it's authenticated if (principal.IsAuthenticated()) { EnsurePersistentCookie(context); return; } ChatUser user = _repository.GetUser(principal); authResult.ProviderName = principal.GetIdentityProvider(); // The user exists so add the claim if (user != null) { if (loggedInUser != null && user != loggedInUser) { // Set an error message authResult.Message = String.Format(LanguageResources.Account_AccountAlreadyLinked, authResult.ProviderName); authResult.Success = false; // Keep the old user logged in context.Identity.AddClaim(new Claim(JabbRClaimTypes.Identifier, loggedInUser.Id)); } else { // Login this user AddClaim(context, user); } } else if (principal.HasRequiredClaims()) { ChatUser targetUser = null; // The user doesn't exist but the claims to create the user do exist if (loggedInUser == null) { // New user so add them user = _membershipService.AddUser(principal); targetUser = user; } else { // If the user is logged in then link _membershipService.LinkIdentity(loggedInUser, principal); _repository.CommitChanges(); authResult.Message = String.Format(LanguageResources.Account_AccountLinkedSuccess, authResult.ProviderName); targetUser = loggedInUser; } AddClaim(context, targetUser); } else if (!principal.HasPartialIdentity()) { // A partial identity means the user needs to add more claims to login context.Identity.AddClaim(new Claim(JabbRClaimTypes.PartialIdentity, "true")); } var cookieOptions = new CookieOptions { HttpOnly = true }; context.Response.Cookies.Append(Constants.AuthResultCookie, JsonConvert.SerializeObject(authResult), cookieOptions); }
private void CheckUserStatus(ILogger logger, IJabbrRepository repo) { var inactiveUsers = new List<ChatUser>(); IQueryable<ChatUser> users = repo.GetOnlineUsers().Where(u => SqlFunctions.DateDiff("mi", u.LastActivity, DateTime.UtcNow) > 5); foreach (var user in users.ToList()) { user.Status = (int)UserStatus.Inactive; inactiveUsers.Add(user); } if (inactiveUsers.Count > 0) { PerformRoomAction(inactiveUsers, async roomGroup => { await _hubContext.Clients.Group(roomGroup.Room.Name).markInactive(roomGroup.Users); }); repo.CommitChanges(); } }
// This is an uber hack to make sure the db is in sync with SignalR private void EnsureClientConnected(ILogger logger, IJabbrRepository repo, ITrackingConnection connection) { var contextField = connection.GetType().GetField("_context", BindingFlags.NonPublic | BindingFlags.Instance); if (contextField == null) { return; } var context = contextField.GetValue(connection) as HostContext; if (context == null) { return; } string connectionData = context.Request.QueryString["connectionData"]; if (String.IsNullOrEmpty(connectionData)) { return; } var hubs = JsonConvert.DeserializeObject <HubConnectionData[]>(connectionData); if (hubs.Length != 1) { return; } // We only care about the chat hub if (!hubs[0].Name.Equals("chat", StringComparison.OrdinalIgnoreCase)) { return; } logger.Log("Connection {0} exists but isn't tracked.", connection.ConnectionId); string userId = context.Request.User.GetUserId(); ChatUser user = repo.GetUserById(userId); if (user == null) { logger.Log("Unable to find user with id {0}", userId); return; } var client = new ChatClient { Id = connection.ConnectionId, User = user, UserAgent = context.Request.Headers["User-Agent"], LastActivity = DateTimeOffset.UtcNow, LastClientActivity = user.LastActivity }; repo.Add(client); repo.CommitChanges(); }
private void UpdatePresence(ILogger logger, IJabbrRepository repo) { // Get all connections on this node and update the activity foreach (var connection in _heartbeat.GetConnections()) { if (!connection.IsAlive) { continue; } ChatClient client = repo.GetClientById(connection.ConnectionId); if (client != null) { client.LastActivity = DateTimeOffset.UtcNow; } else { EnsureClientConnected(logger, repo, connection); } } repo.CommitChanges(); }
public AccountModule(IApplicationSettings applicationSettings, IAuthenticationTokenService authenticationTokenService, IMembershipService membershipService, IJabbrRepository repository, IAuthenticationService authService, IChatNotificationService notificationService) : base("/account") { Get["/"] = _ => { if (Context.CurrentUser == null) { return(HttpStatusCode.Forbidden); } ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); return(GetProfileView(authService, user)); }; Get["/login"] = _ => { if (Context.CurrentUser != null) { return(Response.AsRedirect("~/")); } return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); }; Post["/login"] = param => { if (Context.CurrentUser != null) { return(Response.AsRedirect("~/")); } string username = Request.Form.username; string password = Request.Form.password; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(password)) { this.AddValidationError("password", "Password is required"); } try { if (ModelValidationResult.IsValid) { ChatUser user = membershipService.AuthenticateUser(username, password); return(this.CompleteLogin(authenticationTokenService, user)); } else { return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); } } catch { this.AddValidationError("_FORM", "Login failed. Check your username/password."); return(View["login", GetLoginViewModel(applicationSettings, repository, authService)]); } }; Post["/logout"] = _ => { if (Context.CurrentUser == null) { return(HttpStatusCode.Forbidden); } var response = Response.AsJson(new { success = true }); response.AddCookie(new NancyCookie(Constants.UserTokenCookie, null) { Expires = DateTime.Now.AddDays(-1) }); return(response); }; Get["/register"] = _ => { if (Context.CurrentUser != null) { return(Response.AsRedirect("~/")); } return(View["register"]); }; Post["/create"] = _ => { if (Context.CurrentUser != null) { return(Response.AsRedirect("~/")); } string username = Request.Form.username; string email = Request.Form.email; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(username)) { this.AddValidationError("username", "Name is required"); } if (String.IsNullOrEmpty(email)) { this.AddValidationError("email", "Email is required"); } ValidatePassword(password, confirmPassword); try { if (ModelValidationResult.IsValid) { ChatUser user = membershipService.AddUser(username, email, password); return(this.CompleteLogin(authenticationTokenService, user)); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } return(View["register"]); }; Post["/unlink"] = param => { if (Context.CurrentUser == null) { return(HttpStatusCode.Forbidden); } string provider = Request.Form.provider; ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); if (user.Identities.Count == 1 && !user.HasUserNameAndPasswordCredentials()) { this.AddAlertMessage("error", "You cannot unlink this account because you would lose your ability to login."); return(Response.AsRedirect("~/account/#identityProviders")); } var identity = user.Identities.FirstOrDefault(i => i.ProviderName == provider); if (identity != null) { repository.Remove(identity); this.AddAlertMessage("success", String.Format("Successfully unlinked {0} account.", provider)); return(Response.AsRedirect("~/account/#identityProviders")); } return(HttpStatusCode.BadRequest); }; Post["/newpassword"] = _ => { if (Context.CurrentUser == null) { return(HttpStatusCode.Forbidden); } string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); try { if (ModelValidationResult.IsValid) { membershipService.SetUserPassword(user, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { this.AddAlertMessage("success", "Successfully added a password."); return(Response.AsRedirect("~/account/#changePassword")); } return(GetProfileView(authService, user)); }; Post["/changepassword"] = _ => { if (Context.CurrentUser == null) { return(HttpStatusCode.Forbidden); } string oldPassword = Request.Form.oldPassword; string password = Request.Form.password; string confirmPassword = Request.Form.confirmPassword; if (String.IsNullOrEmpty(oldPassword)) { this.AddValidationError("oldPassword", "Old password is required"); } ValidatePassword(password, confirmPassword); ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserPassword(user, oldPassword, password); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { this.AddAlertMessage("success", "Successfully changed your password."); return(Response.AsRedirect("~/account/#changePassword")); } return(GetProfileView(authService, user)); }; Post["/changeusername"] = _ => { if (Context.CurrentUser == null) { return(HttpStatusCode.Forbidden); } string username = Request.Form.username; string confirmUsername = Request.Form.confirmUsername; ValidateUsername(username, confirmUsername); ChatUser user = repository.GetUserById(Context.CurrentUser.UserName); string oldUsername = user.Name; try { if (ModelValidationResult.IsValid) { membershipService.ChangeUserName(user, username); repository.CommitChanges(); } } catch (Exception ex) { this.AddValidationError("_FORM", ex.Message); } if (ModelValidationResult.IsValid) { notificationService.OnUserNameChanged(user, oldUsername, username); this.AddAlertMessage("success", "Successfully changed your username."); return(Response.AsRedirect("~/account/#changeUsername")); } return(GetProfileView(authService, user)); }; }
private void HandleUnallow(ChatUser user, string[] parts) { if (parts.Length == 1) { throw new InvalidOperationException("Which user to you want to revoke persmissions from?"); } string targetUserName = parts[1]; ChatUser targetUser = _repository.VerifyUser(targetUserName); if (parts.Length == 2) { throw new InvalidOperationException("Which room?"); } string roomName = parts[2]; ChatRoom targetRoom = _repository.VerifyRoom(roomName); _chatService.UnallowUser(user, targetUser, targetRoom); _notificationService.UnallowUser(targetUser, targetRoom); _repository.CommitChanges(); }
public NotificationsModule(IJabbrRepository repository, IChatService chatService, IChatNotificationService notificationService) : base("/notifications") { Get["/"] = _ => { if (!IsAuthenticated) { return(Response.AsRedirect(String.Format("~/account/login?returnUrl={0}", HttpUtility.UrlEncode(Request.Path)))); } var request = this.Bind <NotificationRequestModel>(); ChatUser user = repository.GetUserById(Principal.GetUserId()); int unreadCount = repository.GetUnreadNotificationsCount(user); IPagedList <NotificationViewModel> notifications = GetNotifications(repository, user, all: request.All, page: request.Page, roomName: request.Room); var viewModel = new NotificationsViewModel { ShowAll = request.All, UnreadCount = unreadCount, Notifications = notifications, }; return(View["index", viewModel]); }; Post["/markasread"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } int notificationId = Request.Form.notificationId; Notification notification = repository.GetNotificationById(notificationId); if (notification == null) { return(HttpStatusCode.NotFound); } ChatUser user = repository.GetUserById(Principal.GetUserId()); if (notification.UserKey != user.Key) { return(HttpStatusCode.Forbidden); } notification.Read = true; repository.CommitChanges(); UpdateUnreadCountInChat(repository, notificationService, user); var response = Response.AsJson(new { success = true }); return(response); }; Post["/markallasread"] = _ => { if (!IsAuthenticated) { return(HttpStatusCode.Forbidden); } ChatUser user = repository.GetUserById(Principal.GetUserId()); IList <Notification> unReadNotifications = repository.GetNotificationsByUser(user).Unread().ToList(); if (!unReadNotifications.Any()) { return(HttpStatusCode.NotFound); } foreach (var notification in unReadNotifications) { notification.Read = true; } repository.CommitChanges(); UpdateUnreadCountInChat(repository, notificationService, user); var response = Response.AsJson(new { success = true }); return(response); }; }