123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- using System;
- using System.Linq;
- using System.Threading.Tasks;
- using FMSAdmin.Data;
- using FMSAdmin.Models;
- using FMSAdmin.Entities;
- using FMSAdmin.Services;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Logging;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.EntityFrameworkCore;
- using FMSAdmin.Helpers;
- using System.Data;
- using System.IO;
- using OfficeOpenXml;
- using System.Security.Cryptography;
- using System.Text;
- using System.Net.Mail;
- using System.Net;
- namespace FMSAdmin.Controllers {
- [Authorize]
- [ApiController]
- [ApiVersion("1")]
- [Route("api/users")]
- public class UserController : Controller {
- private readonly ILogger<UserController> _logger;
- private readonly FMSContext _context;
- private readonly UserService _service;
- private readonly StorageHelper _storage;
- public UserController(
- ILogger<UserController> logger,
- FMSContext context,
- UserService service,
- StorageHelper storage
- ) {
- _logger = logger;
- _context = context;
- _service = service;
- _storage = storage;
- }
- /// <summary>
- /// 로그인
- /// </summary>
- [AllowAnonymous]
- [HttpPost("[action]")]
- public IActionResult Login([FromBody] LoginModel model) {
- _logger.LogInformation(model.Dump());
- var user = _service.Login(model);
- if (user == null)
- return BadRequest("아이디나 비밀번호가 잘못되었습니다.");
- if (user.EmploymentStatus == EmploymentStatus.퇴직)
- return BadRequest("로그인 할 수 없습니다.");
- return Ok(new {
- user.SiteId,
- user.UserId,
- user.UserGroupId,
- UserGroup = new {
- user.UserGroupId,
- user.Name,
- },
- user.Name,
- user.OfficePhoneNo,
- user.Email,
- user.PositionId,
- Position = new {
- user.CmPosition?.Name,
- },
- SiteName = user.CmSite?.Name,
- user.RefreshToken,
- user.AccessToken,
- user.IsAdmin,
- user.PasswordUpdatedDate,
- user.IsSysop,
- });
- }
- /// <summary>
- /// 패스워드 변경
- /// </summary>
- [AllowAnonymous]
- [HttpPost("[action]/{siteId}/{id}")]
- public IActionResult ChangePassword(int siteId, string id, [FromForm] string password, [FromForm] string auth) {
- _logger.LogInformation("password:" + password);
- _logger.LogInformation("auth:" + auth);
- // auth 체크는 나중에..
- _service.ChangePassword(siteId, id, password);
- return Ok(id);
- }
- /// <summary>
- /// 목록
- /// </summary>
- [HttpGet]
- public IActionResult List([FromQuery] PagingRequest req, [FromQuery] string str, int? type) {
- _logger.LogInformation(req.Dump());
- var query = _FilterAndSort(req, str);
- if (type != null) query = query.Where(x => x.EmploymentStatus == EmploymentStatus.재직);
- var list = _ListSelect(query);
- var paging = PagingList.Pagination(list, req.page, req.limit);
- return Ok(paging);
- }
- /// <summary>
- /// 엑셀파일 익스포트
- /// </summary>
- [HttpGet("excel")]
- public IActionResult ExportExcel([FromQuery] PagingRequest req, string filename) {
- req.page = 1;
- req.limit = 0;
- var query = _FilterAndSort(req, "");
- var list = _ListSelect(query);
- var stream = new MemoryStream();
- using (var package = new ExcelPackage(stream)) {
- var workSheet = package.Workbook.Worksheets.Add("Sheet1");
- workSheet.Cells.LoadFromCollection(list, true);
- if (req.columns != null && req.columns.Length > 0) {
- workSheet.AddStyle(req.columns, req.sort?.order?.ToLower() == "asc", filename);
- }
- package.Save();
- }
- stream.Position = 0;
- string excelName = $"excel-{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx";
- return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", excelName);
- }
- /// <summary>
- /// 상세조회
- /// </summary>
- [HttpGet("{id}")]
- public IActionResult GetByUserId(string id) {
- var emp = _service.GetByUserId(id);
- if (emp == null)
- return NotFound();
- return Ok(new {
- emp.SiteId,
- emp.UserId,
- emp.UserGroupId,
- emp.Name,
- emp.OfficePhoneNo,
- emp.Email,
- //UserGroupName = emp.CmUserGroup.Name,
- emp.AccessToken,
- });
- }
- /// <summary>
- /// 조회
- /// </summary>
- /// <param name="siteId"></param>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("{siteId}/{id}")]
- public IActionResult Get(int siteId, string id) {
- var data = _service.Gets(id, siteId);
- if (data.Count() == 0) {
- return NotFound("사용자정보를 찾을 수 없습니다.");
- }
- var item = data.Select(x => new {
- x.UserGroupId,
- CmUserGroup = new {
- x.CmUserGroup.Name,
- },
- x.SiteId,
- CmSite = new {
- x.CmSite.Name,
- },
- x.UserId,
- x.Name,
- x.Passwd,
- x.OfficePhoneNo,
- x.Email,
- x.EmploymentStatus,
- EmploymentStatusName = x.EmploymentStatus.ToString(),
- x.EmploymentType,
- EmploymentTypeName = x.EmploymentType.ToString(),
- x.CompanyId,
- CmCompany = new {
- x.CmCompany.Name,
- },
- x.DepartmentId,
- CmDepartment = new {
- x.CmDepartment.Name,
- },
- x.PositionId,
- CmPosition = new {
- x.CmPosition.Name,
- },
- x.BusinessFieldId,
- CmBusinessField = new {
- x.CmBusinessField.Name,
- },
- x.MobilePhoneNo,
- x.EnterDate,
- x.RetireDate,
- x.Certificated,
- x.IsScheduleUser,
- x.IsSi,
- x.IsMobile,
- x.Comment,
- x.IsUse,
- x.IsAdmin,
- CmFile = _storage.ParseFile(x.CmFile),
- CmFile1 = _storage.ParseFile(x.CmFile1),
- });
- return Ok(item.First());
- }
- /// <summary>
- /// 수정
- /// </summary>
- [HttpPost("{siteId}/{id}")]
- public IActionResult Edit(int siteId, string id, [FromBody] CmUser emp) {
- _logger.LogInformation(emp.Dump());
- /*
- var currentUserId = int.Parse(User.Identity.Name);
- if (id != currentUserId)
- return Forbid();
- if (!User.IsInRole(Role.Admin))
- return Forbid();
- */
- if (id != emp.UserId) {
- return NotFound();
- }
- //ModelState.Remove("Password"); // 이 수정에서는 비밀번호 제외
- if (ModelState.IsValid) {
- try {
- _service.Edit(id, siteId, emp);
- } catch (ServiceException ex) {
- return BadRequest(ex.Message);
- }
- } else {
- foreach (var ms in ModelState.ToArray()) {
- _logger.LogInformation(ms.Key);
- }
- return BadRequest(ModelState);
- }
- return Ok();
- }
- /// <summary>
- /// 등록
- /// </summary>
- [HttpPut]
- public IActionResult Create([FromBody] CmUser emp) {
- // if (!User.IsInRole("Admin"))
- // return Forbid();
- if (ModelState.IsValid) {
- try {
- _service.Create(emp);
- } catch (ServiceException ex) {
- return BadRequest(ex.Message);
- }
- } else {
- return BadRequest(ModelState);
- }
- return Ok();
- }
- /// <summary>
- /// 삭제
- /// </summary>
- [HttpDelete("{siteId}/{id}")]
- public IActionResult Delete(int siteId, string id) {
- _service.Delete(id, siteId);
- return Ok();
- }
- // Role 제한 테스트
- [AllowAnonymous]
- [HttpGet("auth")]
- public IActionResult Auth() {
- return Ok();
- }
- // 검색 & 정렬 공통
- private IQueryable<CmUser> _FilterAndSort(PagingRequest req, string str) {
- var query = _service.GetAll();
- // 기본 Entity 검색
- query = query.Filter(req.conditions);
- // 추가 검색 예제
- /*
- if (req.conditions != null) {
- foreach (var cond in req.conditions) {
- switch ($"{cond.field}_{cond.op}") {
- case "fffff_eq":
- query = query.Where(x => x.Name == cond.value);
- break;
- }
- }
- }
- */
- //query = query.Where(x => x.IsUse == true);
- //아이콘트롤스 시스템 관리자 HIDDEN
- query = query.Where(x => x.IsSysop == false);
- if (req.siteId != null) {
- query = query.Where(x => x.SiteId == Util.ToInt(req.siteId));
- }
- if (req.siteIds != null && req.siteIds.Length > 0) {
- query = query.Where(x => req.siteIds.Contains(x.SiteId));
- }
- // 업무분야 필드가 있는경우만 추가
- if (req.businessFieldId != null) {
- query = query.Where(x => x.SiteId == req.siteId);
- query = query.Where(x => x.BusinessFieldId == req.businessFieldId || x.CmBusinessField.Name == "공통");
- }
- if (str != null) {
- query = query.Where(x => x.UserId.Contains(str) || x.Name.Contains(str));
- }
- // 추가 정렬 예제
- /*
- if (req.sort != null) {
- switch ($"{req.sort.field}_{req.sort.order}") {
- case "userId_asc":
- query = query.OrderBy(x => x.UserId);
- break;
- case "userId_desc":
- query = query.OrderByDescending(x => x.UserId);
- break;
- }
- }
- */
- // 고정정렬 (사옥 준공순)
- var sortQuery = query.OrderBy(x => x.CmSite.SortOrderNo);
- sortQuery = sortQuery.ThenByDescending(x => x.CmPosition.Position);
- // 추가 정렬
- sortQuery = sortQuery.ThenSort(req.sort);
- return sortQuery;
- }
- // 셀렉트 공통
- private dynamic _ListSelect(IQueryable<CmUser> query) {
- var list = query.Select(x => new {
- x.SiteId,
- SiteName = x.CmSite.Name,
- x.UserId,
- x.UserGroupId,
- x.Name,
- CmUserGroup = new {
- x.CmUserGroup.UserGroupId,
- x.CmUserGroup.Name
- },
- UserGroupName = x.CmUserGroup.Name,
- x.EmploymentStatus,
- EmploymentStatusName = x.EmploymentStatus.ToString(),
- x.OfficePhoneNo,
- x.MobilePhoneNo,
- x.Email,
- x.AccessToken,
- CmCompanyNm = new {
- x.CmCompany.Name
- },
- CompanyName = x.CmCompany.Name,
- CmDepartment = new {
- x.CmDepartment.Name
- },
- DepartmentName = x.CmDepartment.Name,
- Dept = x.CmCompany.Name + '/' + x.CmPosition.Name,
- PositionName = x.CmPosition.Name,
- BusinessFieldName = x.CmBusinessField.Name,
- x.EmploymentType,
- EmploymentTypeName = x.EmploymentType.ToString(),
- CmFile = _storage.ParseFile(x.CmFile)
- });
- return list;
- }
- /// <summary>
- /// 로그인 - 사이트 ID 조회
- /// </summary>
- [AllowAnonymous]
- [HttpGet("GetSite")]
- public IActionResult GetSite() {
- var site = _service.GetCmSites();
- if (site == null)
- return BadRequest("사이트 정보를 가져오지 못했습니다.");
- var list = site.Select(x => new {
- Id = x.SiteId,
- x.Name,
- });
- return Ok(list);
- }
- [AllowAnonymous]
- [HttpPost("[action]/{reqid}/{email}")]
- public IActionResult SendEmailAuthCode(string email, string reqid) {
- // 요청번호 reqid 무시. 안쓰고있음
- if (string.IsNullOrEmpty(email)) {
- return BadRequest("이메일을 입력해주세요.");
- }
- email = email.Trim();
- var query = _service.GetAll().Where(x => x.Email == email);
- if (query.Count() == 0) {
- return BadRequest("이메일과 일치하는 회원이 없습니다.");
- }
- if (query.Count() > 1) {
- return BadRequest("동일한 이메일이 여러개 존재합니다.");
- }
- string authCode = "" + new Random().Next(10000, 99999);
- _logger.LogInformation("authCode:" + authCode);
- var user = query.FirstOrDefault();
- // 이메일 발송
- using (var message = new MailMessage()) {
- message.To.Add(new MailAddress(email, user.Name));
- message.From = new MailAddress("hdc.icontrols.rnd1@gmail.com", "FMS");
- message.Subject = "FMS 비밀번호 찾기 인증번호";
- message.Body = $"<div style='width:800px; padding:30px; text-align:center;font-size:20pt;'>{user.Name}님의 아이디는 {user.UserId.Substring(0, user.UserId.Length - 2)}** 입니다.<br/><br/><div style='font-size:15pt'>보안을 위해 아래 인증번호를 입력하시고,<br/>비밀번호를 새로 설정해 주시기 바랍니다.</div><br/><strong>인증번호 : {authCode}</strong></div>";
- message.IsBodyHtml = true;
- var smtp = new SmtpClient {
- Host = "smtp.gmail.com",
- Port = 587,
- EnableSsl = true,
- DeliveryMethod = SmtpDeliveryMethod.Network,
- Credentials = new NetworkCredential("hdc.icontrols.rnd1@gmail.com", "pwrd12#$"),
- Timeout = 20000
- };
- smtp.Send(message);
- }
- // 검증용 코드 출력
- string code = null;
- using (SHA256 mySHA256 = SHA256.Create()) {
- code = Convert.ToBase64String(mySHA256.ComputeHash(Encoding.UTF8.GetBytes(email + authCode))).Replace("+", ".").Replace("/", "_").Replace("=", "-");
- }
- return Ok(code);
- }
- [AllowAnonymous]
- [HttpPost("[action]/{authCode}/{code}/{email}")]
- public IActionResult ValidAuthCode(string authCode, string code, string email) {
- string check = "";
- if (string.IsNullOrEmpty(email)) {
- return BadRequest("이메일을 입력해주세요.");
- }
- if (string.IsNullOrEmpty(authCode)) {
- return BadRequest("인증번호를 입력해주세요.");
- }
- var query = _service.GetAll().Where(x => x.Email == email);
- if (query.Count() == 0) {
- return BadRequest("이메일과 일치하는 회원이 없습니다.");
- }
- if (query.Count() > 1) {
- return BadRequest("동일한 이메일이 여러개 존재합니다.");
- }
- var member = query.FirstOrDefault();
- // 검증용 코드로 검증
- authCode = authCode.Trim();
- using (SHA256 mySHA256 = SHA256.Create()) {
- check = Convert.ToBase64String(mySHA256.ComputeHash(Encoding.UTF8.GetBytes(email + authCode))).Replace("+", ".").Replace("/", "_").Replace("=", "-");
- }
- if (code != check) {
- return BadRequest("인증번호가 일치하지 않습니다.");
- }
- // 검증완료 비밀번호 초기화
- _service.ChangePassword(member.SiteId, member.UserId, member.UserId, true);
- return Ok(new {
- SiteId = member.SiteId,
- UserId = member.UserId,
- });
- }
- }
- }
|