public async Task <IActionResult> EmailConfigUpdate([FromBody] EmailSettingsViewModel model) { if (model == null) { return(BadRequest(ModelState)); } AppSetting oldSetting = null; var setting = await Db.AppSettings.GetEmailSettingsAsync(); if (setting == null) { setting = new AppSetting { Name = EMAIL_SETTINGS_NAME }; await Db.AppSettings.AddAsync(setting); } else { oldSetting = setting.Clone(); } setting.Value = Newtonsoft.Json.JsonConvert.SerializeObject(model); await Db.SaveChangesAsync(); await EventLogger.LogAsync(SysEventType.EmailConfigUpdated, await FindUserAsync(), setting, oldSetting); return(Ok()); }
public async Task <IActionResult> Put([FromBody] TicketModificationViewModel model) { var issue = await Db.GetIssueAsync(model.Id, GetUserId(), false); if (issue == null) { return(NotFound()); } // clone the issue before altering it var oldIssue = issue.Clone(); issue.Body = model.Body; issue.Subject = model.Subject; var success = await Db.UpdateIssueAsync(issue, CurrentUserId, newStatus : TicketStatus.Unchanged, save : true); if (success) { var cmt = await Db.AddSysCommentAsync(TicketUpdated, issue.Id); await Db.AddFileAttachementAsync(oldIssue, cmt.Id, CurrentUserId); await EventLogger.LogAsync(SysEventType.IssueUpdated, CurrentUserId, issue, oldIssue); } return(new OkObjectResult(success ? TicketUpdated : TicketNotUpdated)); }
public async Task <IActionResult> Post([FromBody] RegistrationViewModel model) { var appUser = _mapper.Map <AppUser>(model); var result = await UserManager.CreateAsync(appUser, model.Password); if (!result.Succeeded) { return(new BadRequestObjectResult(Errors.AddErrors(ModelState, result))); } await Db.Employees.AddAsync(new Employee { UserId = appUser.Id, Location = model.Location }); await Db.SaveChangesAsync(); if (string.Equals(model.Mode, "admin", System.StringComparison.OrdinalIgnoreCase)) { await EventLogger.LogAsync(SysEventType.UserCreated, await FindUserAsync(), appUser); } else { await EventLogger.LogAsync(SysEventType.UserRegistered, appUser); } return(Ok()); }
public async Task <IActionResult> PostLogout(string id) { try { var user = await FindUserAsync(id); if (user != null) { await EventLogger.LogAsync(SysEventType.Logout, user, Request.Host.Host); } } catch { } return(Ok()); }
public async Task <IActionResult> TakeOver(int id) { Issue issue = null; if (!await Db.CanTakeOverAsync(GetUserId(), id, iss => issue = iss)) { return(BadRequest()); } issue.AssignedToUserId = CurrentUserId; if (await Db.UpdateIssueAsync(issue, CurrentUserId, save: true, logUpdate: false)) { await EventLogger.LogAsync(SysEventType.IssueAssigned, CurrentUserId, issue); } return(Ok()); }
public async Task <IActionResult> Post([FromBody] TicketRegistrationViewModel model) { var issue = new Issue { Body = model.Body, Subject = model.Subject, CategoryId = model.CategoryId, UpdatedByUser = true, StatusId = (int)TicketStatus.New, UserId = GetUserId(), Priority = model.Priority, }; await Db.Issues.AddAsync(issue); await Db.SaveChangesAsync(); await EventLogger.LogAsync(SysEventType.IssueCreated, issue.UserId, issue); return(Ok()); }
public async Task <IActionResult> ImportUsers() { try { var file = Request.Form.Files[0]; if (file == null || file.Length <= 0L) { return(BadRequest(ModelState)); } var user = await FindUserAsync(); if (!user.IsAdministrator) { return(BadRequest()); } var content = await new FormFileReader(file).ReadAsStringAsync(); await new UserDataImporter(UserManager, Db, _mapper).ImportAsync(content , onCreating: au => { au.SendEmail = true; } , onCreated: async au => { await EventLogger.LogAsync(SysEventType.UserImported, user, au); } , onFailed: (ui, ir) => { }); } catch (Exception ex) { return(BadRequest(ex)); } return(Ok()); }
public async Task <IActionResult> CategoryDetail([FromBody] CategoryDetailViewModel model) { try { var oldCat = await Db.Categories.FindAsync(model.Id); if (oldCat == null) { return(NotFound()); } // update the category accordingly var entity = _mapper.Map <Category>(model); if (!(model.DifferentFrom ?? false)) { entity.FromAddress = null; entity.FromName = null; entity.FromAddressInReplyTo = false; } // detach the old category to avoid trouble Db.Entry(oldCat).State = EntityState.Detached; // set the new state for the entity Db.Entry(entity).State = EntityState.Modified; await Db.SaveChangesAsync(); await EventLogger.LogAsync(SysEventType.CategoryUpdated, await FindUserAsync(), entity, oldCat); return(Ok()); } catch (Exception ex) { return(BadRequest(ex)); } }
public async Task <IActionResult> Post([FromBody] CredentialsViewModel credentials) { var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password); if (identity == null) { await EventLogger.LogAsync(SysEventType.LoginFailure, credentials.UserName); return(BadRequest(ModelState.AddError("login_failure", BadLoginAttempt))); } var userId = identity.Claims.Single(c => c.Type == "id").Value; var user = await FindUserAsync(userId); var jwt = await identity.GenerateJwtAsync(userId, credentials.UserName, user.UserRole(), _jwtFactory, _jwtOptions); await EventLogger.LogAsync(SysEventType.LoginSuccess, user, Request.Host.Host); return(new OkObjectResult(jwt.Json())); }
public async Task <IActionResult> ChangePassword([FromBody] ChangePasswordModel model) { var emp = await FindEmployeeAsync(model.UserId); if (emp?.User == null) { return(NotFound()); } var target = emp.User; var is_admin = await IsAdmin(); var is_builtin = await IsBuiltInAdmin(); var is_self = emp.UserId == GetUserId(); var hasPwd = await UserManager.HasPasswordAsync(target); var OldPasswordHash = string.Empty; if (hasPwd) { OldPasswordHash = target.PasswordHash; } if (!is_self) { // somebody's trying to update another user if (!is_admin) { // a non-administrator cannot update another user return(BadRequest()); } if (!is_builtin && target.IsAdministrator) { // only the built-in administrator can modify another admin return(BadRequest()); } return(await change_admin_pwd()); } else if (is_admin || is_builtin) { return(await change_admin_pwd()); } else if (string.IsNullOrWhiteSpace(model.OldPassword)) { return(BadRequest(ModelState.AddError(string.Empty, ChangePasswordOldRequired))); } // when simple users change their password IdentityResult result; if (hasPwd) { result = await UserManager.ChangePasswordAsync(target, model.OldPassword, model.NewPassword); } else { result = await UserManager.AddPasswordAsync(target, model.NewPassword); } if (result.Succeeded) { return(await change_pwd_success()); } return(BadRequest(ModelState.AddError(string.Empty, ChangePasswordBadAttempt))); // when an admin changes a user's password, no need to specify the old one async Task <IActionResult> change_admin_pwd() { IdentityResult res; if (hasPwd) { target.PasswordHash = UserManager.PasswordHasher.HashPassword(target, model.NewPassword); res = await UserManager.UpdateAsync(target); } else { res = await UserManager.AddPasswordAsync(target, model.NewPassword); } if (res.Succeeded) { return(await change_pwd_success()); } return(BadRequest(ModelState.AddError(string.Empty, ChangePasswordFailed))); } async Task <IActionResult> change_pwd_success() { var user = target; if (!is_self) { user = await FindUserAsync(); } await EventLogger.LogAsync(SysEventType.UserPasswordChanged, user, target, new { UserId = user.Id, OldPasswordHash }); return(Ok()); } }
public async Task <IActionResult> UserDetail([FromBody] UserDetailViewModel model) { var emp = await FindEmployeeAsync(model.Id, true); if (emp == null) { return(NotFound()); } // now do some heavy-weight lifting var target = emp.User; var is_tech = target.IsTech; var is_self = emp.UserId == GetUserId(); var is_admin = await IsAdmin(); var is_builtin = await IsBuiltInAdmin(); // check if logged-in user can modify this model if (!is_self) { if (!is_admin) { // a non-administrator cannot update another user return(BadRequest()); } if (target.IsAdministrator && !is_builtin) { // only the built-in administrator can modify another admin return(BadRequest()); } } var oldEmp = emp.Clone(); if (model.CompanyId == null || model.CompanyId < 0) { if (!string.IsNullOrWhiteSpace(model.CompanyName)) { var comp = await Db.GetOrCreateCompanyAsync(model.CompanyName); emp.CompanyId = comp.Id; } } else { emp.CompanyId = model.CompanyId; } if (model.DepartmentId == null || model.DepartmentId < 0) { if (!string.IsNullOrWhiteSpace(model.DepartmentName)) { try { var depmt = await Db.Departments.Where(d => d.Name == model.DepartmentName).FirstOrDefaultAsync(); if (depmt == null) { depmt = new Department { Name = model.DepartmentName.Trim() }; await Db.Departments.AddAsync(depmt); await Db.SaveChangesAsync(); } emp.DepartmentId = depmt.Id; } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex); throw; } } } else { emp.DepartmentId = model.DepartmentId; } emp.Gender = model.Gender; emp.Locale = model.Locale; emp.Location = model.Location; emp.PhoneNumberExtension = model.PhoneExtension; emp.Signature = model.Signature; target.Email = model.Email; target.FacebookId = model.FacebookId; target.FirstName = model.FirstName; target.LastName = model.LastName; target.Greeting = model.Greeting; target.Notes = model.Notes; target.PhoneNumber = model.Phone; target.PictureUrl = model.PictureUrl; target.SendEmail = model.SendEmail; target.TwoFactorEnabled = model.TwoFactor; if (is_tech || is_admin) { target.SendNewTicketTechEmail = model.SendNewTicketTechEmail; } else { target.SendNewTicketTechEmail = false; } // one cannot disable its own account (maybe the built-in only to avoid exploitation when not used?) if (!is_self && is_admin) { target.Disabled = model.Disabled; } // user roles update requirements: // 1. users must be administrators // 2. admins cannot update their own roles, even not the built-in (who would then perform system-wide troubleshooting?) if (is_admin && !is_self && !string.IsNullOrWhiteSpace(model.Role)) { var update = true; // almost there if (!is_builtin && await IsAdmin(target.Id)) { // 3. when target is admin then only built-in should be able to update it update = false; } if (update) { // good switch (model.Role.ToUpperInvariant()) { case "ADMIN": target.IsAdministrator = true; target.IsTech = false; target.IsManager = false; break; case "TECH": target.IsAdministrator = false; target.IsTech = true; target.IsManager = false; break; default: target.IsAdministrator = false; target.IsTech = false; target.IsManager = model.IsManager; break; } } } await Db.SaveChangesAsync(); await EventLogger.LogAsync(SysEventType.UserUpdated, await FindUserAsync(), target, oldEmp); return(Ok()); }
public async Task <IActionResult> OnPostAsync(string returnUrl = null) { if (ModelState.IsValid) { var settings = await _settingsManager.GetSettingsAsync <SecuritySettings>(); #if !DEBUG if (settings.ValidCode && !IsValidateCode("login", Input.Code)) { ModelState.AddModelError("Input.Code", "验证码不正确!"); return(Page()); } #endif returnUrl = returnUrl ?? Url.GetDirection(settings.LoginDirection); Input.UserName = Input.UserName.Trim(); Input.Password = Input.Password.Trim(); // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true var result = await _userManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, async user => await EventLogger.LogAsync(user.UserId, Resources.EventType, "成功登录系统。")); if (result.Succeeded) { Response.Cookies.Delete("login"); return(LocalRedirect(returnUrl)); } if (result.RequiresTwoFactor) { return(RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, Input.RememberMe })); } if (result.IsLockedOut) { Logger.LogWarning($"账号:{Input.UserName}被锁定。"); return(RedirectToPage("./Lockout")); } ModelState.AddModelError(string.Empty, "用户名或密码错误。"); return(Page()); } // If we got this far, something failed, redisplay form return(Page()); }
public async Task <IActionResult> Index(SigninUser model, string returnUrl = null) { try { var settings = await _settingsManager.GetSettingsAsync <SecuritySettings>(); #if !DEBUG if (settings.ValidCode && !IsValidateCode("login", model.Code)) { return(Error("验证码错误!")); } #endif returnUrl = returnUrl ?? Url.GetDirection(settings.LoginDirection); model.UserName = model.UserName.Trim(); model.Password = model.Password.Trim(); var result = await _userManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, async user => await EventLogger.LogAsync(user.UserId, Resources.EventType, "成功登录系统。")); if (result.Succeeded) { Response.Cookies.Delete("login"); return(Success(new { url = returnUrl })); } if (result.RequiresTwoFactor) { return(Success(new { reurl = Url.Page("/LoginWith2fa", new { model.RememberMe, returnUrl, area = SecuritySettings.ExtensionName }) })); } if (result.IsLockedOut) { Logger.LogWarning($"账户[{model.UserName}]被锁定。"); return(Error("账户被锁定!")); } } catch (Exception ex) { Logger.LogError(ex, $"账户[{model.UserName}]登录失败:{ex.Message}"); } Logger.LogWarning($"账户[{model.UserName}]登录失败。"); return(Error("用户名或密码错误!")); }