From a101dac949a62aaa5818ad16f6d1e114669f7504 Mon Sep 17 00:00:00 2001 From: qnill Date: Tue, 12 Sep 2017 12:47:36 +0300 Subject: [PATCH] Fixes #31 : User module done. --- .../Controllers/Account/AccountController.cs | 145 ++++++++++++------ RS.Core.Api/Models/AccountBindingModels.cs | 21 +++ RS.Core.Api/Web.config | 4 +- RS.Core.Service/RS.Core.Service.csproj | 1 + RS.Core.Service/Services/User/UserService.cs | 58 ++++++- 5 files changed, 178 insertions(+), 51 deletions(-) diff --git a/RS.Core.Api/Controllers/Account/AccountController.cs b/RS.Core.Api/Controllers/Account/AccountController.cs index 5b0a5bf..dd145d4 100644 --- a/RS.Core.Api/Controllers/Account/AccountController.cs +++ b/RS.Core.Api/Controllers/Account/AccountController.cs @@ -1,25 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Security.Cryptography; -using System.Threading.Tasks; -using System.Web; -using System.Web.Http; -using System.Web.Http.ModelBinding; -using Microsoft.AspNet.Identity; +using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.OAuth; +using RS.Core.Const; using RS.Core.Models; using RS.Core.Providers; using RS.Core.Results; -using RS.Core.Service.DTOs; using RS.Core.Service; -using RS.Core.Const; +using RS.Core.Service.DTOs; +using System; +using System.Collections.Generic; using System.Net; +using System.Net.Http; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Threading.Tasks; +using System.Web; +using System.Web.Http; +using System.Web.Http.Description; namespace RS.Core.Controllers { @@ -131,7 +131,7 @@ public async Task ChangePassword(ChangePasswordBindingModel m IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword); - + if (!result.Succeeded) { return GetErrorResult(result); @@ -264,9 +264,9 @@ public async Task GetExternalLogin(string provider, string er if (hasRegistered) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); - - ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, - OAuthDefaults.AuthenticationType); + + ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, + OAuthDefaults.AuthenticationType); ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager, CookieAuthenticationDefaults.AuthenticationType); @@ -339,7 +339,7 @@ public async Task Register(RegisterBindingModel model) //You can implement your external user table. #region ExternalUserTable - APIResult customUserResult = await userService.Add(model, Guid.Parse(user.Id)); + APIResult customUserResult = await userService.Register(model, Guid.Parse(user.Id)); if (customUserResult.Message != Messages.Ok) return Content(HttpStatusCode.BadRequest, customUserResult); @@ -385,48 +385,99 @@ public async Task RegisterExternal(RegisterExternalBindingMod result = await UserManager.AddLoginAsync(user.Id, info.Login); if (!result.Succeeded) { - return GetErrorResult(result); + return GetErrorResult(result); } return Ok(); } - ////GET api/Account/RemindPassword?=Email - //[AllowAnonymous] - //[Route("RemindPassword"), HttpGet] - //public async Task RemindPassword(string email) - //{ - // var user = await UserManager.FindByEmailAsync(email); - // if (user == null) - // return BadRequest(Messages.GNE0001); + // PUT api/Account/Update + [Route("Update"), HttpPut] + public async Task Update(UserUpdateDto model) + { + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var result = await userService.Update(model, IdentityClaimsValues.UserID()); + + if (result.Message != Messages.Ok) + return Content(HttpStatusCode.BadRequest, result); + + return Ok(result); + } + + // GET api/Account/RemindPassword?=email + [AllowAnonymous] + [Route("RemindPassword"), HttpGet] + public async Task RemindPassword(string email) + { + var user = await UserManager.FindByEmailAsync(email); + if (user == null) + return BadRequest(Messages.GNE0001); + + string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); + + var result = userService.RemindPassword(email, code, user.Id); + + if (result.Message != Messages.Ok) + return Content(HttpStatusCode.BadRequest, result); + + return Ok(result); + } + + // POST api/Account/ResetPassword + [AllowAnonymous] + [Route("ResetPassword"), HttpPost] + public async Task ResetPassword(ResetPasswordBindingModel model) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + + IdentityResult result = await UserManager.ResetPasswordAsync(model.ID, model.Code, model.NewPassword); - // string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); + if (!result.Succeeded) + { + return GetErrorResult(result); + } - // var result = userService.RemindPasswordMail(email, code, user.Id); + return Ok(); + } - // if (result.Message != Messages.Ok) - // return Content(HttpStatusCode.BadRequest, result); + // GET api/Account/Get + [Route("Get"), HttpGet] + [ResponseType(typeof(IEnumerable))] + public async Task GetByID(Guid id) + { + var result = await userService.GetByID(id); - // return Ok(result); - //} + return Ok(result); + } - ////POST api/Account/ResetPassword - //[AllowAnonymous, Route("ResetPassword"), HttpPost] - //public async Task ResetPassword(ResetPasswordBindingModel model) - //{ - // if (!ModelState.IsValid) - // { - // return BadRequest(ModelState); - // } + // GET api/Account/Get + [Route("Get"), HttpGet] + [ResponseType(typeof(IEnumerable))] + public async Task GetList(string name = null, string email = null) + { + var result = await userService.GetList(name, email); + + if (result == null || result.Count <= 0) + result = new List(); - // IdentityResult result = await UserManager.ResetPasswordAsync(model.ID, model.Code, model.NewPassword); + return Ok(result); + } - // if (!result.Succeeded) - // { - // return GetErrorResult(result); - // } + // GET api/Account/GetSelectList + [Route("GetSelectList"), HttpGet] + public async Task AutoCompleteList(Guid? id = null, string text = null) + { + var result = await userService.AutoCompleteList(id, text); - // return Ok(); - //} + if (result == null) + return Content(HttpStatusCode.OK, new string[0]); + + return Ok(result); + } protected override void Dispose(bool disposing) { diff --git a/RS.Core.Api/Models/AccountBindingModels.cs b/RS.Core.Api/Models/AccountBindingModels.cs index 7824176..cc2e3bb 100644 --- a/RS.Core.Api/Models/AccountBindingModels.cs +++ b/RS.Core.Api/Models/AccountBindingModels.cs @@ -77,4 +77,25 @@ public class SetPasswordBindingModel [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] public string ConfirmPassword { get; set; } } + + public class ResetPasswordBindingModel + { + [Required] + [Display(Name = "Code")] + public string Code { get; set; } + + [Required] + public string ID { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "New password")] + public string NewPassword { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm new password")] + [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + } } diff --git a/RS.Core.Api/Web.config b/RS.Core.Api/Web.config index e9a8b45..5a63499 100644 --- a/RS.Core.Api/Web.config +++ b/RS.Core.Api/Web.config @@ -14,7 +14,9 @@ - + + + diff --git a/RS.Core.Service/RS.Core.Service.csproj b/RS.Core.Service/RS.Core.Service.csproj index 6d28a53..6465582 100644 --- a/RS.Core.Service/RS.Core.Service.csproj +++ b/RS.Core.Service/RS.Core.Service.csproj @@ -74,6 +74,7 @@ + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll diff --git a/RS.Core.Service/Services/User/UserService.cs b/RS.Core.Service/Services/User/UserService.cs index b86728e..c08b1ab 100644 --- a/RS.Core.Service/Services/User/UserService.cs +++ b/RS.Core.Service/Services/User/UserService.cs @@ -1,25 +1,35 @@ using AutoMapper; +using AutoMapper.QueryableExtensions; using RS.Core.Const; using RS.Core.Domain; +using RS.Core.Lib.Email; using RS.Core.Service.DTOs; using System; +using System.Collections; +using System.Collections.Generic; +using System.Configuration; using System.Data.Entity; +using System.Linq; using System.Threading.Tasks; namespace RS.Core.Service { public interface IUserService : IBaseService { - Task Add(UserAddDto model, Guid identityUserID); + Task Register(UserAddDto model, Guid identityUserID); + APIResult RemindPassword(string email, string code, string id); + Task> GetList(string name = null, string email = null); } public class UserService : BaseService, IUserService { - public UserService(EntityUnitofWork _uow) : base(_uow) + private IEmailService emailService; + public UserService(EntityUnitofWork _uow, IEmailService _emailService) : base(_uow) { + emailService = _emailService; } - public async Task Add(UserAddDto model, Guid identityUserID) + public async Task Register(UserAddDto model, Guid identityUserID) { var duplicateUserCheck = await uow.Repository().Query().AnyAsync(x => x.Email == model.Email); if (duplicateUserCheck) @@ -36,5 +46,47 @@ public async Task Add(UserAddDto model, Guid identityUserID) return new APIResult { Data = entity.ID, Message = Messages.Ok }; } + + public APIResult RemindPassword(string email, string code, string id) + { + try + { + ArrayList EmailGroup = new ArrayList(); + EmailGroup.Add(email); + + EmailDto emailModel = new EmailDto + { + EmailGroup = EmailGroup, + Subject = "RS Support", + BackgroundColor = "b61528", + Header = "Password Change Request", + Content = "We understand you're having trouble logging into your account. We can help you regain access to your account. " + + "You can create a new password by clicking on the 'Change Password' button If this is not the case, you can ask our support team for help by emailing support@remmsoft.com.", + ButtonValue = "Change Password", + //`resetPasswordUrl` is get from Web.Config. + URL = ConfigurationManager.AppSettings["resetPasswordUrl"] + "?id=" + id + "?code=" + code + }; + + emailService.SendMail(emailModel); + return new APIResult { Message = Messages.Ok }; + } + catch (Exception ex) + { + return new APIResult { Message = ex.Message }; + } + } + + public async Task> GetList(string name=null, string email=null) + { + var query = uow.Repository().Query(); + + if (name != null) + query = query.Where(x => x.Name.Contains(name)); + if (email != null) + query = query.Where(x => x.Email.Contains(email)); + + return await query.ProjectTo().ToListAsync(); + } + } } \ No newline at end of file