using System; using System.Globalization; using System.IdentityModel.Tokens.Jwt; using System.IO; using System.Linq; using System.Net.Http.Headers; using System.Security.Claims; using System.Text; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using QuizplusApi.Models; using QuizplusApi.Models.Others; using QuizplusApi.Models.User; using QuizplusApi.Services; using QuizplusApi.ViewModels.Helper; using QuizplusApi.ViewModels.Payment; using QuizplusApi.ViewModels.User; namespace QuizplusApi.Controllers { [ApiController] [Route("api/[controller]/[action]")] public class UserController:ControllerBase { private readonly IConfiguration _config; private readonly AppDbContext _context; private readonly ISqlRepository _userRepo; private readonly ISqlRepository _userRoleRepo; private readonly ISqlRepository _logHistoryRepo; public UserController(IConfiguration config, AppDbContext context, ISqlRepository userRepo, ISqlRepository userRoleRepo, ISqlRepository logHistoryRepo) { _config=config; _context = context; _userRepo = userRepo; _userRoleRepo=userRoleRepo; _logHistoryRepo=logHistoryRepo; } /// ///Get Log in Detail /// [AllowAnonymous] [HttpGet("{email}/{password}")] public ActionResult GetLoginInfo(string email, string password) { try { var user=(from u in _context.Users join r in _context.UserRoles on u.UserRoleId equals r.UserRoleId join b in _context.BillingPayments on u.PaymentId equals b.BillingPaymentId into ps from b in ps.DefaultIfEmpty() where u.IsActive.Equals(true) && u.Email.Equals(email) && u.Password.Equals(password) select new {u.UserId,r.UserRoleId,r.RoleName,r.DisplayName,u.FullName,u.Mobile,u.Email, u.ImagePath,u.Password,u.Address,u.DateOfBirth,u.AddedBy,u.PaymentId, Plan=(b==null?"n/a":b.Title), ExpiryDate=(b==null?"n/a":b.EndDate.ToString("yyyy/M/dd",CultureInfo.InvariantCulture)), IsExpired=(b==null?"n/a":(DateTime.UtcNow.Date>b.EndDate?"true":"false"))}).FirstOrDefault(); if(user!=null) { UserInfo userInfo=new UserInfo{UserId=user.UserId,UserRoleId=user.UserRoleId,RoleName=user.RoleName,DisplayName=user.DisplayName, Email=user.Email,Password=user.Password,FullName=user.FullName,Mobile=user.Mobile,Address=user.Address, ImagePath=user.ImagePath,DateOfBirth=user.DateOfBirth,AddedBy=user.AddedBy,PaymentId=user.PaymentId, PlanName=user.Plan,PlanExpiryDate=user.ExpiryDate,IsPlanExpired=user.IsExpired}; var token=GenerateJwtToken(userInfo); return Ok(new LogInResponse{Token=token,Obj=userInfo}); } return NoContent(); } catch (Exception ex) { return Accepted(new Confirmation{Status="error",ResponseMsg=ex.Message}); } } /// ///Get User Info for Forget password option /// [AllowAnonymous] [HttpGet("{email}")] public ActionResult GetUserInfoForForgetPassword(string email) { try { var user=_context.Users.SingleOrDefault(q=>q.Email==email); if(user!=null) { return Ok(user); } else { return Accepted(new Confirmation{Status="error",ResponseMsg="There is no user for this email"}); } } catch (Exception ex) { return Accepted(new Confirmation{Status="error",ResponseMsg=ex.Message}); } } /// ///Admin Registration /// [AllowAnonymous] [HttpPost] public ActionResult AdminRegistration(Users model) { try { bool duplicateRegistration=false; if(model.StripeSessionId!="") { var chkDuplicateSessionId=_context.Users.SingleOrDefault(p=>p.StripeSessionId==model.StripeSessionId); if(chkDuplicateSessionId!=null) { duplicateRegistration=true; } } var chkDuplicate=_context.Users.SingleOrDefault(p=>p.Email==model.Email); if(duplicateRegistration) { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "Please pay first. This is an invalid session!" }); } else if(chkDuplicate==null) { using var transaction = _context.Database.BeginTransaction(); model.UserRoleId=1; model.AddedBy=1; model.DateAdded=DateTime.Now; model.IsActive=true; if(model.StripeSessionId!="") { model.PaymentMode="Online"; model.TransactionDetail=model.StripeSessionId; } else { model.PaymentMode="N/A"; } var obj=_userRepo.Insert(model); if(model.StripeSessionId!="") { var objBilling=_context.BillingPayments.SingleOrDefault(p=>p.StripeSessionId==model.StripeSessionId); objBilling.UserEmail=model.Email; objBilling.AddedBy=model.UserId; _context.SaveChanges(); var objUpdatePayment=_context.Users.FirstOrDefault(q=>q.UserId==obj.UserId); objUpdatePayment.PaymentId=objBilling.BillingPaymentId; _context.SaveChanges(); } else { BillRegister objBillRegister=new BillRegister(); objBillRegister.TransactionEmail=model.Email; objBillRegister.AddedBy=obj.UserId; objBillRegister.TransactionDetail=model.TransactionDetail; objBillRegister.StripeSessionId=""; objBillRegister.PaymentMode=model.PaymentMode; objBillRegister.Price=_context.BillingPlans.FirstOrDefault(q=>q.BillingPlanId==model.BillingPlanId).Price; PaymentService objPaymentService=new PaymentService(_context); int paymentId=objPaymentService.InsertBillingPayment(objBillRegister); if(paymentId>0) { var objUpdatePayment=_context.Users.FirstOrDefault(q=>q.UserId==obj.UserId); objUpdatePayment.PaymentId=paymentId; _context.SaveChanges(); } } SiteSettings objSettings=new SiteSettings(); objSettings.Port=587; objSettings.Host="smtp.gmail.com"; objSettings.Currency="usd"; objSettings.CurrencySymbol="$"; objSettings.IsActive=true; objSettings.DateAdded=DateTime.Now; objSettings.IsMigrationData=false; objSettings.AddedBy=obj.UserId; _context.SiteSettings.Add(objSettings); _context.SaveChanges(); transaction.Commit(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully saved" }); } else { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "This Email already have a user!" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Student Registration /// [AllowAnonymous] [HttpPost] public ActionResult StudentRegistration(Users model) { try { var chkDuplicate=_context.Users.SingleOrDefault(p=>p.Email==model.Email); var chkParticipant=_context.QuizParticipants.FirstOrDefault(p=>p.Email==model.Email && p.AddedBy==model.AddedBy); if(chkParticipant==null) { return Accepted(new Confirmation { Status = "error", ResponseMsg = "This email not allowed to register. Please check!" }); } else if(chkDuplicate==null) { model.UserRoleId=2; model.DateAdded=DateTime.Now; model.IsActive=true; _userRepo.Insert(model); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully saved" }); } else { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "This Email already have a user!" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Create History Log /// [AllowAnonymous] [HttpPost] public ActionResult CreateLoginHistory(LogHistory model) { try { model.LogDate=DateTime.Now; model.LogInTime=DateTime.Now; model.LogCode=Guid.NewGuid().ToString(); model.AdminId=_context.Users.SingleOrDefault(q=>q.UserId==model.UserId).AddedBy; _logHistoryRepo.Insert(model); return Ok(new Confirmation { Status = "success", ResponseMsg = model.LogCode }); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Update Login History /// [AllowAnonymous] [HttpGet("{logCode}")] public ActionResult UpdateLoginHistory(string logCode) { try { var objLogHistory=_context.LogHistories.SingleOrDefault(opt=>opt.LogCode==logCode); objLogHistory.LogOutTime=DateTime.Now; _context.SaveChanges(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully saved" }); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Get Browsing List /// [Authorize(Roles="Admin,SuperAdmin")] [HttpGet] public ActionResult GetBrowseList() { try { var browsingList=_context.LogHistories.Join(_context.Users, log=>log.UserId, user=>user.UserId, (log,user)=>new{ FullName=user.FullName, Email=user.Email, LogInTime=log.LogInTime, LogOutTime=log.LogOutTime, Ip=log.Ip, Browser=log.Browser, BrowserVersion=log.BrowserVersion, Platform=log.Platform }).OrderByDescending(e=>e.LogInTime); return Ok(browsingList); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Get User List /// [HttpGet("{userId}")] [Authorize(Roles="Admin,SuperAdmin")] public ActionResult GetUserList(int userId) { try { var objRole=_context.Users.SingleOrDefault(q=>q.UserId==userId); if(objRole.UserRoleId==3) { var userList=(from u in _context.Users join r in _context.UserRoles on u.UserRoleId equals r.UserRoleId join p in _context.BillingPlans on u.BillingPlanId equals p.BillingPlanId join b in _context.BillingPayments on u.PaymentId equals b.BillingPaymentId into ps from b in ps.DefaultIfEmpty() where u.AddedBy.Equals(userId) && u.UserId!=userId orderby u.DateAdded descending select new {u.UserId,u.UserRoleId,u.FullName,r.RoleName,r.DisplayName,u.Mobile,u.Email,u.Password,u.DateOfBirth, u.Address,u.ImagePath,u.PaymentMode,u.TransactionDetail,p.BillingPlanId,p.Title,p.Interval,u.PaymentId, ExpireyDate=(b==null?"n/a":b.EndDate.ToString("yyyy/M/dd",CultureInfo.InvariantCulture))}); return Ok(userList); } else { var userList=(from u in _context.Users join r in _context.UserRoles on u.UserRoleId equals r.UserRoleId where u.AddedBy.Equals(userId) && u.UserId!=userId orderby u.DateAdded descending select new {u.UserId,u.UserRoleId,u.FullName,r.RoleName,r.DisplayName,u.Mobile,u.Email,u.Password,u.DateOfBirth, u.Address,u.ImagePath}); return Ok(userList); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Get Single User by id /// [HttpGet("{id}")] [Authorize(Roles="Admin,SuperAdmin,Student")] public ActionResult GetSingleUser(int id) { try { var singleUser=_userRepo.SelectById(id); return Ok(singleUser); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Delete User by User Id /// [HttpDelete("{id}")] [Authorize(Roles="Admin,SuperAdmin")] public ActionResult DeleteSingleUser(int id) { try { var chkMigration=_context.Users.FirstOrDefault(q=>q.UserId==id); if(chkMigration.IsMigrationData) { return Accepted(new Confirmation { Status = "error", ResponseMsg = "Not allowed to delete this on demo version!" }); } else { _userRepo.Delete(id); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully deleted" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Create User /// [Authorize(Roles="Admin,SuperAdmin")] [HttpPost] public ActionResult CreateUser(Users model) { try { var chkDuplicate=_context.Users.SingleOrDefault(p=>p.Email.ToLower()==model.Email.ToLower()); if(chkDuplicate==null) { using var transaction = _context.Database.BeginTransaction(); model.DateAdded=DateTime.Now; model.IsActive=true; var obj=_userRepo.Insert(model); if(model.UserRoleId==1) { BillRegister objBillRegister=new BillRegister(); objBillRegister.TransactionEmail=model.Email; objBillRegister.AddedBy=obj.UserId; objBillRegister.TransactionDetail=model.TransactionDetail; objBillRegister.StripeSessionId=""; objBillRegister.PaymentMode=model.PaymentMode; objBillRegister.Price=_context.BillingPlans.FirstOrDefault(q=>q.BillingPlanId==model.BillingPlanId).Price; PaymentService objPaymentService=new PaymentService(_context); int paymentId=objPaymentService.InsertBillingPayment(objBillRegister); if(paymentId>0) { var objUpdatePayment=_context.Users.FirstOrDefault(q=>q.UserId==obj.UserId); objUpdatePayment.PaymentId=paymentId; _context.SaveChanges(); } SiteSettings objSettings=new SiteSettings(); objSettings.Port=587; objSettings.Host="smtp.gmail.com"; objSettings.Currency="usd"; objSettings.CurrencySymbol="$"; objSettings.IsActive=true; objSettings.DateAdded=DateTime.Now; objSettings.IsMigrationData=false; objSettings.AddedBy=obj.UserId; _context.SiteSettings.Add(objSettings); _context.SaveChanges(); } transaction.Commit(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully saved" }); } else { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "This Email already have a user!" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Update User /// [Authorize(Roles="Admin,SuperAdmin")] [HttpPut] public ActionResult UpdateUser(Users model) { try { var objUser=_context.Users.SingleOrDefault(p=>p.UserId==model.UserId); var objCheck=_context.Users.SingleOrDefault(p=>p.Email.ToLower()==model.Email.ToLower()); if(objCheck!=null && objCheck.Email.ToLower()!=objUser.Email.ToLower()) { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "This Email already have a user!" }); } else { objUser.UserRoleId=model.UserRoleId; objUser.FullName=model.FullName; objUser.Mobile=model.Mobile; objUser.Email=model.Email; objUser.DateOfBirth=model.DateOfBirth; objUser.Address=model.Address; objUser.Password=model.Password; objUser.ImagePath=model.ImagePath; objUser.LastUpdatedBy=model.LastUpdatedBy; objUser.LastUpdatedDate=DateTime.Now; _context.SaveChanges(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully updated" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Update User Profile /// [Authorize(Roles="Admin,SuperAdmin,Student")] [HttpPut] public ActionResult UpdateUserProfile(UserInfo model) { try { var objUser=_context.Users.SingleOrDefault(opt=>opt.UserId==model.UserId); objUser.FullName=model.FullName; objUser.Mobile=model.Mobile; objUser.Address=model.Address; objUser.DateOfBirth=model.DateOfBirth; objUser.ImagePath=model.ImagePath; objUser.LastUpdatedBy=model.LastUpdatedBy; objUser.LastUpdatedDate=DateTime.Now; _context.SaveChanges(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully updated" }); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Change User Password /// [Authorize(Roles="Admin,SuperAdmin,Student")] [HttpPut] public ActionResult ChangeUserPassword(UserInfo model) { try { var objUser=_context.Users.SingleOrDefault(opt=>opt.UserId==model.UserId); objUser.Password=model.Password; _context.SaveChanges(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully changed" }); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Profile picture upload /// [Authorize(Roles="Admin,SuperAdmin,Student")] [HttpPost, DisableRequestSizeLimit] public IActionResult Upload() { try { var file = Request.Form.Files[0]; var folderName = Path.Combine("Resources", "ProfileImages"); var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName); if (file.Length > 0 && file.ContentType.StartsWith("image/")) { var fileName = Guid.NewGuid().ToString()+"_"+ ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); var fullPath = Path.Combine(pathToSave, fileName); var dbPath = Path.Combine(folderName, fileName); using (var stream = new FileStream(fullPath, FileMode.Create)) { file.CopyTo(stream); } return Ok(new { dbPath }); } else { return Accepted(new Confirmation { Status = "error", ResponseMsg = "Not an image" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Get Role List /// [Authorize(Roles="SuperAdmin,Admin")] [HttpGet] public ActionResult GetUserRoleList() { try { var userRoleList=_userRoleRepo.SelectAll(); return Ok(userRoleList); } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Delete Role by id /// [HttpDelete("{id}")] [Authorize(Roles="SuperAdmin")] public ActionResult DeleteSingleRole(int id) { try { if(id==1 || id==2) { return Accepted(new Confirmation { Status = "restricted", ResponseMsg = "This Role is restricted to delete." }); } else { _userRoleRepo.Delete(id); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully deleted" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Create User Role /// [Authorize(Roles="SuperAdmin")] [HttpPost] public ActionResult CreateUserRole(UserRole model) { try { var objCheck=_context.UserRoles.SingleOrDefault(opt=>opt.RoleName.ToLower()==model.RoleName.ToLower()); if(objCheck==null) { model.DateAdded=DateTime.Now; model.IsActive=true; _userRoleRepo.Insert(model); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully saved" }); } else { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "Duplicate Role name!" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } /// ///Update User Role /// [Authorize(Roles="SuperAdmin")] [HttpPut] public ActionResult UpdateUserRole(UserRole model) { try { var objUserRole=_context.UserRoles.SingleOrDefault(opt=>opt.UserRoleId==model.UserRoleId); var objCheck=_context.UserRoles.SingleOrDefault(opt=>opt.RoleName.ToLower()==model.RoleName.ToLower()); if(objCheck!=null && objCheck.RoleName.ToLower()!=objUserRole.RoleName.ToLower()) { return Accepted(new Confirmation { Status = "duplicate", ResponseMsg = "Duplicate User Role name!" }); } else if(model.UserRoleId==1 || model.UserRoleId==2) { objUserRole.DisplayName=model.DisplayName; objUserRole.RoleDesc=model.RoleDesc; objUserRole.LastUpdatedBy=model.LastUpdatedBy; objUserRole.LastUpdatedDate=DateTime.Now; _context.SaveChanges(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully updated" }); } else { objUserRole.RoleName=model.RoleName; objUserRole.DisplayName=model.DisplayName; objUserRole.RoleDesc=model.RoleDesc; objUserRole.LastUpdatedBy=model.LastUpdatedBy; objUserRole.LastUpdatedDate=DateTime.Now; _context.SaveChanges(); return Ok(new Confirmation { Status = "success", ResponseMsg = "Successfully updated" }); } } catch (Exception ex) { return Accepted(new Confirmation { Status = "error", ResponseMsg = ex.Message }); } } string GenerateJwtToken(UserInfo userInfo) { var securityKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:SecretKey"])); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, userInfo.UserId.ToString()), new Claim("fullName", userInfo.FullName.ToString()), new Claim("role",userInfo.RoleName), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), }; var token = new JwtSecurityToken( issuer: _config["Jwt:Issuer"], audience: _config["Jwt:Audience"], claims: claims, expires: DateTime.Now.AddMinutes(360), signingCredentials: credentials ); return new JwtSecurityTokenHandler().WriteToken(token); } } }