Beispiel #1
0
        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());
        }
Beispiel #7
0
        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());
        }
Beispiel #8
0
        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()));
        }
Beispiel #10
0
        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());
            }
        }
Beispiel #11
0
        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());
        }
Beispiel #12
0
        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());
        }
Beispiel #13
0
        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("用户名或密码错误!"));
        }