<repo_name>YotsaponDev/Project_bkk_api<file_sep>/Models/Permission/RoleRepository.cs
﻿using Core.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Project_bkk_api.Models.Permission;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class RoleRepository : IRole
    {
        private DataContext _context;

        private IConfiguration configuration;

        public RoleRepository(DataContext context, IConfiguration iConfig)
        {
            _context = context;
            configuration = iConfig;
        }

        public List<RoleEntity> GetAll()
        {
            return _context.role.Where(x => x.deleted_at == null).ToList();
        }

        public RoleEntity GetById(Guid id)
        {
            return _context.role.Find(id);
        }

        public RoleEntity Create(RoleEntity model)
        {
            model.id = Guid.NewGuid();
            model.deleted_at = null;
            _context.role.Add(model);
            _context.SaveChanges();
            return model;
        }

        public RoleEntity Update(Guid id, RoleEntity modelUpdate)
        {
            var data = _context.role.Find(id);

            data.name = modelUpdate.name;
            data.note = modelUpdate.note;
            data.is_active = modelUpdate.is_active;
            //data.created_by = modelUpdate.created_by;
            //data.created_at = modelUpdate.created_at;
            data.updated_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }

        public RoleEntity Delete(Guid id)
        {
            var data = _context.role.Find(id);

            data.deleted_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }  
    }
}
<file_sep>/Models/Permission/StaffHasRoleEntity.cs
﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class StaffHasRoleEntity
    {
        [Key]
        public Guid id { get; set; }

        [ForeignKey("staff_id")]
        public StaffEntity Staff { get; set; }
        public Guid staff_id { get; set; }

        [ForeignKey("role_id")]
        public RoleEntity Role { get; set; }
        public Guid role_id { get; set; }

        public bool is_active { get; set; }

        public Guid? created_by { get; set; }

        public DateTime? created_at { get; set; }

        public Guid? updated_by { get; set; }

        public DateTime? updated_at { get; set; }

        public DateTime? deleted_at { get; set; }
    }
}
<file_sep>/Models/Staff/StaffRepository.cs
﻿using Core.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Project_bkk_api.Models.Staff;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class StaffRepository : IStaff
    {
        private DataContext _context;

        private IConfiguration configuration;

        public StaffRepository(DataContext context, IConfiguration iConfig)
        {
            _context = context;
            configuration = iConfig;
        }

        public List<StaffEntity> GetAll()
        {
            return _context.staff.Where(x => x.deleted_at == null).ToList();
        }

        public StaffEntity GetById(Guid id)
        {
            return _context.staff.Find(id);
        }

        public StaffReturnViewModel GetByIdViaJWT(string authHeader)
        {
            var handler = new JwtSecurityTokenHandler();
            string[] auth = authHeader.Split(" ");

            var exp = handler.ReadJwtToken(auth[1]).Payload.Exp;

            DateTime now = DateTime.Now;
            var date = now;

            var lifeTime = new JwtSecurityTokenHandler().ReadToken(auth[1]).ValidTo.ToLocalTime();

            var id = handler.ReadJwtToken(auth[1]).Payload.Jti;
            var staff = _context.staff.Find(Guid.Parse(id));
            var data = new StaffReturnViewModel();
            data.id = staff.id;
            data.firstname = staff.firstname;
            data.lastname = staff.lastname;
            data.username = staff.username;
            data.email = staff.email;

            return data;
        }

        public StaffEntity Create(StaffEntity model)
        {

            var staff = _context.staff.Where(x => x.username == model.username || x.email == model.email).FirstOrDefault();

            if(staff == null)
            {
                model.id = Guid.NewGuid();
                model.deleted_at = null;
                model.password = <PASSWORD>(model.password);
                _context.staff.Add(model);
                _context.SaveChanges();

                model.password = <PASSWORD>;
                return model;
            }
            else
            {
                if (staff.username == model.username)
                {
                    throw new Exception("Username already exists");
                } else if (staff.email == model.email)
                {
                    throw new Exception("Email already exists");
                }
                else
                {
                    throw new Exception("Username and Email already exists");
                }
                
            } 
        }

        public object Login(StaffLoginViewModel model)
        {
            var checkPassword = <PASSWORD>ToMD5(model.password);
            var staff = _context.staff.Where(x => x.username == model.username && x.password == checkPassword).FirstOrDefault();

            if (staff == null)
            {
                throw new Exception();
            }
            else
            {
                var claims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Jti, staff.id.ToString())
                    //new Claim(JwtRegisteredClaimNames.NameId, user.username),
                    //new Claim(JwtRegisteredClaimNames.GivenName, user.firstname),
                    //new Claim(JwtRegisteredClaimNames.FamilyName, user.lastname),
                    //new Claim(JwtRegisteredClaimNames.Email, user.email)
                };
                string key = configuration.GetSection("JWT").GetSection("SecurityKey").Value;
                var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));

                var token = new JwtSecurityToken(
                    expires: DateTime.Now.AddSeconds(5),
                    claims: claims,
                    signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
                    );

                // find role
                var role_name = (from shr in _context.staff_has_role where shr.staff_id == staff.id 
                          join r in _context.role on shr.role_id equals r.id into r2
                          from f in r2.DefaultIfEmpty()
                          select new  {
                            f.name,f.id
                           }).ToList();

                List<string> roleNameArr = new List<string>();
                List<string> permissionNameArr = new List<string>();

                if (role_name != null)
                {
                    int rnC = role_name.Count;
                    for (int i = 0; i < rnC; i++)
                    {
                     
                        // find permission
                        var pn = (from rhp in _context.role_has_permission
                                  where rhp.role_id == role_name[i].id
                                  join p in _context.permission on rhp.permission_id equals p.id into p2
                                  from f in p2.DefaultIfEmpty()
                                  select new
                                  {
                                      f.name,
                                      f.id
                                  }).ToList();
                        int pnC = pn.Count;
                        for (int j = 0; j < pnC; j++)
                        {
                            permissionNameArr.Add(pn[j].name);
                        }
                    }
                }
                string[] roleNameArray = roleNameArr.ToArray();
                string[] permissionNameArray = permissionNameArr.ToArray();

                var return_token = new {
                    access_token = new JwtSecurityTokenHandler().WriteToken(token),
                    role = roleNameArray,
                    permission = permissionNameArray
                };

                return return_token;
            }   
        }

        static string StringToMD5(string value)
        {
            using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
            {
                UTF8Encoding utf8 = new UTF8Encoding();
                byte[] data = md5.ComputeHash(utf8.GetBytes(value));
                return Convert.ToBase64String(data);
            }
        }

        public StaffEntity Update(Guid id, StaffEntity modelUpdate)
        {
            var data = _context.staff.Find(id);

            data.firstname = modelUpdate.firstname;
            data.lastname = modelUpdate.lastname;
            data.is_active = modelUpdate.is_active;
            //data.created_by = modelUpdate.created_by;
            //data.created_at = modelUpdate.created_at;
            data.updated_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }

        public StaffEntity Delete(Guid id)
        {
            var data = _context.staff.Find(id);

            data.deleted_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }  
    }
}
<file_sep>/Models/Staff/IStaff.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Todo.Models;

namespace Project_bkk_api.Models.Staff
{
    public interface IStaff
    {
        List<StaffEntity> GetAll();
        StaffEntity GetById(Guid id);
        StaffReturnViewModel GetByIdViaJWT(string authHeader);
        StaffEntity Create(StaffEntity model);
        StaffEntity Update(Guid id, StaffEntity modelUpdate);
        StaffEntity Delete(Guid id);
        object Login(StaffLoginViewModel model);
    }
}
<file_sep>/Data/Migrations/25620724102632_Migration001.cs
﻿using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Project_bkk_api.Data.Migrations
{
    public partial class Migration001 : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "laws",
                columns: table => new
                {
                    id = table.Column<Guid>(nullable: false),
                    name = table.Column<string>(maxLength: 255, nullable: true),
                    note = table.Column<string>(maxLength: 3000, nullable: true),
                    is_active = table.Column<bool>(nullable: true),
                    created_by = table.Column<Guid>(nullable: true),
                    created_at = table.Column<DateTime>(nullable: true),
                    updated_by = table.Column<Guid>(nullable: true),
                    updated_at = table.Column<DateTime>(nullable: true),
                    delete_at = table.Column<DateTime>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_laws", x => x.id);
                });

            migrationBuilder.CreateTable(
                name: "staff",
                columns: table => new
                {
                    id = table.Column<Guid>(nullable: false),
                    fullname = table.Column<string>(maxLength: 255, nullable: true),
                    position = table.Column<int>(maxLength: 255, nullable: false),
                    ad_username = table.Column<string>(maxLength: 255, nullable: true),
                    password = table.Column<string>(maxLength: 255, nullable: true),
                    email = table.Column<string>(maxLength: 255, nullable: true),
                    tel = table.Column<string>(maxLength: 255, nullable: true),
                    is_active = table.Column<bool>(nullable: true),
                    created_by = table.Column<Guid>(nullable: true),
                    created_at = table.Column<DateTime>(nullable: true),
                    updated_by = table.Column<Guid>(nullable: true),
                    updated_at = table.Column<DateTime>(nullable: true),
                    delete_at = table.Column<DateTime>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_staff", x => x.id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "laws");

            migrationBuilder.DropTable(
                name: "staff");
        }
    }
}
<file_sep>/Models/Laws/ILaws.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Todo.Models;

namespace Project_bkk_api.Models.Laws
{
    public interface ILaws
    {
        List<LawsEntity> GetAll();
        LawsEntity GetById(Guid id);
        LawsEntity Create(LawsEntity model);
        LawsEntity Update(Guid id, LawsEntity modelUpdate);
        LawsEntity Delete(Guid id);
    }
}
<file_sep>/Data/Migrations/25620820084305_Migration005.cs
﻿using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Project_bkk_api.Data.Migrations
{
    public partial class Migration005 : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "permission",
                columns: table => new
                {
                    id = table.Column<Guid>(nullable: false),
                    name = table.Column<string>(maxLength: 255, nullable: true),
                    note = table.Column<Guid>(maxLength: 2000, nullable: false),
                    is_active = table.Column<bool>(nullable: false),
                    created_by = table.Column<Guid>(nullable: true),
                    created_at = table.Column<DateTime>(nullable: true),
                    updated_by = table.Column<Guid>(nullable: true),
                    updated_at = table.Column<DateTime>(nullable: true),
                    deleted_at = table.Column<DateTime>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_permission", x => x.id);
                });

            migrationBuilder.CreateTable(
                name: "role",
                columns: table => new
                {
                    id = table.Column<Guid>(nullable: false),
                    name = table.Column<string>(maxLength: 255, nullable: true),
                    note = table.Column<Guid>(maxLength: 2000, nullable: false),
                    is_active = table.Column<bool>(nullable: false),
                    created_by = table.Column<Guid>(nullable: true),
                    created_at = table.Column<DateTime>(nullable: true),
                    updated_by = table.Column<Guid>(nullable: true),
                    updated_at = table.Column<DateTime>(nullable: true),
                    deleted_at = table.Column<DateTime>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_role", x => x.id);
                });

            migrationBuilder.CreateTable(
                name: "role_has_permission",
                columns: table => new
                {
                    id = table.Column<Guid>(nullable: false),
                    role_id = table.Column<Guid>(nullable: false),
                    permission_id = table.Column<Guid>(nullable: false),
                    is_active = table.Column<bool>(nullable: false),
                    created_by = table.Column<Guid>(nullable: true),
                    created_at = table.Column<DateTime>(nullable: true),
                    updated_by = table.Column<Guid>(nullable: true),
                    updated_at = table.Column<DateTime>(nullable: true),
                    deleted_at = table.Column<DateTime>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_role_has_permission", x => x.id);
                    table.ForeignKey(
                        name: "FK_role_has_permission_permission_permission_id",
                        column: x => x.permission_id,
                        principalTable: "permission",
                        principalColumn: "id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_role_has_permission_role_role_id",
                        column: x => x.role_id,
                        principalTable: "role",
                        principalColumn: "id",
                        onDelete: ReferentialAction.Cascade);
                });

            migrationBuilder.CreateTable(
                name: "staff_has_role",
                columns: table => new
                {
                    id = table.Column<Guid>(nullable: false),
                    staff_id = table.Column<Guid>(nullable: false),
                    role_id = table.Column<Guid>(nullable: false),
                    is_active = table.Column<bool>(nullable: false),
                    created_by = table.Column<Guid>(nullable: true),
                    created_at = table.Column<DateTime>(nullable: true),
                    updated_by = table.Column<Guid>(nullable: true),
                    updated_at = table.Column<DateTime>(nullable: true),
                    deleted_at = table.Column<DateTime>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_staff_has_role", x => x.id);
                    table.ForeignKey(
                        name: "FK_staff_has_role_role_role_id",
                        column: x => x.role_id,
                        principalTable: "role",
                        principalColumn: "id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_staff_has_role_staff_staff_id",
                        column: x => x.staff_id,
                        principalTable: "staff",
                        principalColumn: "id",
                        onDelete: ReferentialAction.Cascade);
                });

            migrationBuilder.CreateIndex(
                name: "IX_role_has_permission_permission_id",
                table: "role_has_permission",
                column: "permission_id");

            migrationBuilder.CreateIndex(
                name: "IX_role_has_permission_role_id",
                table: "role_has_permission",
                column: "role_id");

            migrationBuilder.CreateIndex(
                name: "IX_staff_has_role_role_id",
                table: "staff_has_role",
                column: "role_id");

            migrationBuilder.CreateIndex(
                name: "IX_staff_has_role_staff_id",
                table: "staff_has_role",
                column: "staff_id");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "role_has_permission");

            migrationBuilder.DropTable(
                name: "staff_has_role");

            migrationBuilder.DropTable(
                name: "permission");

            migrationBuilder.DropTable(
                name: "role");
        }
    }
}
<file_sep>/Models/Permission/IRoleHasPermission.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Todo.Models;

namespace Project_bkk_api.Models.Permission
{
    public interface IRoleHasPermission
    {
        List<RoleHasPermissionEntity> GetAll();
        RoleHasPermissionEntity GetById(Guid id);
        RoleHasPermissionViewModel Create(RoleHasPermissionViewModel model);
        //RoleHasPermissionEntity Update(Guid id, RoleHasPermissionEntity modelUpdate);
        RoleHasPermissionEntity Delete(Guid id);
    }
}
<file_sep>/Models/Permission/IRole.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Todo.Models;

namespace Project_bkk_api.Models.Permission
{
    public interface IRole
    {
        List<RoleEntity> GetAll();
        RoleEntity GetById(Guid id);
        RoleEntity Create(RoleEntity model);
        RoleEntity Update(Guid id, RoleEntity modelUpdate);
        RoleEntity Delete(Guid id);
    }
}
<file_sep>/Data/Migrations/25620819082929_Migration004.cs
﻿using Microsoft.EntityFrameworkCore.Migrations;

namespace Project_bkk_api.Data.Migrations
{
    public partial class Migration004 : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.RenameColumn(
                name: "fullname",
                table: "staff",
                newName: "username");

            migrationBuilder.RenameColumn(
                name: "delete_at",
                table: "staff",
                newName: "deleted_at");

            migrationBuilder.RenameColumn(
                name: "ad_username",
                table: "staff",
                newName: "lastname");

            migrationBuilder.AlterColumn<string>(
                name: "position",
                table: "staff",
                maxLength: 255,
                nullable: true,
                oldClrType: typeof(int),
                oldMaxLength: 255);

            migrationBuilder.AlterColumn<bool>(
                name: "is_active",
                table: "staff",
                nullable: false,
                oldClrType: typeof(bool),
                oldNullable: true);

            migrationBuilder.AddColumn<string>(
                name: "firstname",
                table: "staff",
                maxLength: 255,
                nullable: true);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "firstname",
                table: "staff");

            migrationBuilder.RenameColumn(
                name: "username",
                table: "staff",
                newName: "fullname");

            migrationBuilder.RenameColumn(
                name: "lastname",
                table: "staff",
                newName: "ad_username");

            migrationBuilder.RenameColumn(
                name: "deleted_at",
                table: "staff",
                newName: "delete_at");

            migrationBuilder.AlterColumn<int>(
                name: "position",
                table: "staff",
                maxLength: 255,
                nullable: false,
                oldClrType: typeof(string),
                oldMaxLength: 255,
                oldNullable: true);

            migrationBuilder.AlterColumn<bool>(
                name: "is_active",
                table: "staff",
                nullable: true,
                oldClrType: typeof(bool));
        }
    }
}
<file_sep>/Controllers/LawsController.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Project_bkk_api.Models;
using Microsoft.Extensions.Logging;
using Core.Data;
using Todo.Models;
using Project_bkk_api.Models.Laws;

namespace Project_bkk_api.Controllers
{
    [Route("api/Laws")]
    public class LawsController : Controller
    {
        private ILogger<LawsController> _logger;

        private readonly ILaws _laws;

        public LawsController(ILaws laws)
        {
            _laws = laws;
        }

        /// <summary>
        /// Laws get all data
        /// </summary>
        /// <remarks>
        /// Laws get all data
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns all data</response>
        /// <response code="500">Error Occurred</response>  
        [HttpGet("")]
        [ProducesResponseType(typeof(List<LawsViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetAll()
        {
            try
            {
                var data = _laws.GetAll();
                return Json(data);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Laws get By Id
        /// </summary>
        /// <remarks>
        /// Laws get By Id
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpGet("GetById")]
        [ProducesResponseType(typeof(List<LawsViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetById(Guid id)
        {
            try
            {
                var data = _laws.GetById(id);
                return Json(data);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Laws create item
        /// </summary>
        /// <remarks>
        /// Laws create item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpPost]
        [ProducesResponseType(typeof(List<LawsViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Create([FromBody] LawsEntity model)
        {
            try
            {
                if (model != null)
                {
                    _laws.Create(model);
                }
                return Json(model);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Laws Update item
        /// </summary>
        /// <remarks>
        /// Laws Update item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpPut("{id}")]
        [ProducesResponseType(typeof(List<LawsViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Update(Guid id, [FromBody] LawsEntity model)
        {
            try
            {
                if (id == null)
                {
                    return StatusCode(400, $"ID is not valid.");
                }
                else
                {
                    var res = _laws.Update(id, model);
                    return Json(res);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Laws Update item
        /// </summary>
        /// <remarks>
        /// Laws Update item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpDelete("{id}")]
        [ProducesResponseType(typeof(List<LawsViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Delete(Guid id)
        {
            try
            {
                if (id == null)
                {
                    return StatusCode(400, $"ID is not valid.");
                }
                else
                {
                    var res = _laws.Delete(id);
                    return Json(res);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }
    }
}
<file_sep>/Controllers/StaffController.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Project_bkk_api.Models;
using Microsoft.Extensions.Logging;
using Core.Data;
using Todo.Models;
using Project_bkk_api.Models.Staff;
using Microsoft.AspNetCore.Authorization;
using System.Net.Http.Headers;

namespace Project_bkk_api.Controllers
{
    [Authorize]
    [Route("api/Staff")]
    public class StaffController : Controller
    {
        private ILogger<StaffController> _logger;

        private readonly IStaff _staff;

        public StaffController(IStaff staff)
        {
            _staff = staff;
        }

        /// <summary>
        /// Staff get all data
        /// </summary>
        /// <remarks>
        /// Staff get all data
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns all data</response>
        /// <response code="500">Error Occurred</response>  
        [AllowAnonymous]
        [HttpGet("")]
        [ProducesResponseType(typeof(List<StaffViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetAll()
        {
            try
            {
                var data = _staff.GetAll();
                return Json(data);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Staff get By Id
        /// </summary>
        /// <remarks>
        /// Staff get By Id
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [AllowAnonymous]
        [HttpGet("GetById")]
        [ProducesResponseType(typeof(List<StaffViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetById(Guid id)
        {
            try
            {
                var data = _staff.GetById(id);
                return Json(data);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Staff get By Id via JWT
        /// </summary>
        /// <remarks>
        /// Staff get By Id via JWT
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpGet("GetByIdViaJWT")]
        [ProducesResponseType(typeof(StaffReturnViewModel), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetByIdViaJWT()
        {
            try
            {
                var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
                if (authHeader == null)
                {
                    throw new Exception("AuthorizationNone");
                }
                else
                {
                    var data = _staff.GetByIdViaJWT(authHeader.ToString());
                    return Json(data);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Staff create item
        /// </summary>
        /// <remarks>
        /// Staff create item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="409">Conflict</response>  
        [AllowAnonymous]
        [HttpPost]
        [ProducesResponseType(typeof(List<StaffViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(409)]
        public IActionResult Create([FromBody] StaffEntity model)
        {
            try
            {
                if (model != null)
                {
                    var x = _staff.Create(model);
                    return Json(x);
                }
                else
                {
                    return Json(model);
                }
            }
            catch (Exception ex)
            {
                return StatusCode(409, $"{ex.Message}");
            }
        }

        /// <summary>
        /// Staff Login
        /// </summary>
        /// <remarks>
        /// Staff Login
        /// </remarks>
        /// <returns>Return staff login</returns>
        /// <response code="200">Returns token</response>
        /// <response code="500">Error Occurred</response>  
        [AllowAnonymous]
        [Route("Login")]
        [HttpPost]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(401)]
        public IActionResult Login([FromBody] StaffLoginViewModel model)
        {
            try
            {
                if (model != null)
                {
                    var x = _staff.Login(model);
                    return Json(x);
                }
                return null;
            }
            catch (Exception ex)
            {
                //_logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(401, "LoginFailure");
            }
        }

        /// <summary>
        /// Staff Update item
        /// </summary>
        /// <remarks>
        /// Staff Update item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpPut("{id}")]
        [ProducesResponseType(typeof(List<StaffViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Update(Guid id, [FromBody] StaffEntity model)
        {
            try
            {
                if (id == null)
                {
                    return StatusCode(400, $"ID is not valid.");
                }
                else
                {
                    var res = _staff.Update(id, model);
                    return Json(res);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Staff Update item
        /// </summary>
        /// <remarks>
        /// Staff Update item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpDelete("{id}")]
        [ProducesResponseType(typeof(List<StaffViewModel>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Delete(Guid id)
        {
            try
            {
                if (id == null)
                {
                    return StatusCode(400, $"ID is not valid.");
                }
                else
                {
                    var res = _staff.Delete(id);
                    return Json(res);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }
    }
}
<file_sep>/Models/User/UserEntity.cs
﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class UserEntity
    {
        [Key]
        public Guid id { get; set; }

        [Description("ชื่อ")]
        [MaxLength(255)]
        public string firstname { get; set; }

        [Description("นามสกุล")]
        [MaxLength(255)]
        public string lastname { get; set; }

        [Description("ชื่อบริษัทหรือนิติบุคคล")]
        [MaxLength(255)]
        public string full_company_name { get; set; }

        [Description("ประเภทนิติบุคคล")]
        [MaxLength(255)]
        public string type { get; set; }

        [Description("ชื่อผู้ใช้งาน")]
        [MaxLength(255)]
        public string username { get; set; }

        [Description("รหัสผ่าน")]
        [MaxLength(255)]
        public string password { get; set; }

        [Description("อีเมล์")]
        [MaxLength(255)]
        public string email { get; set; }

        [Description("สถานะการใช้งาน")]
        public bool is_active { get; set; }

        [Description("อีเมล์")]
        public DateTime? created_at { get; set; }

        [Description("วันเวลาที่แก้ไข")]
        public DateTime? updated_at { get; set; }

        [Description("วันเวลาที่ลบ")]
        public DateTime? deleted_at { get; set; }

    }
}
<file_sep>/Models/Laws/LawsRepository.cs
﻿using Core.Data;
using Microsoft.EntityFrameworkCore;
using Project_bkk_api.Models.Laws;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class LawsRepository : ILaws
    {
        private DataContext _context;

        public LawsRepository(DataContext context)
        {
            _context = context;
        }

        public List<LawsEntity> GetAll()
        {
            return _context.laws.Where(x => x.deleted_at == null).ToList();
        }

        public LawsEntity GetById(Guid id)
        {
            return _context.laws.Find(id);
        }

        public LawsEntity Create(LawsEntity model)
        {
            model.id = Guid.NewGuid();
            model.deleted_at = null;
            _context.laws.Add(model);
            _context.SaveChanges();

            return model;
        }

        public LawsEntity Update(Guid id, LawsEntity modelUpdate)
        {
            var data = _context.laws.Find(id);

            data.name = modelUpdate.name;
            data.note = modelUpdate.note;
            data.is_active = modelUpdate.is_active;
            //data.created_by = modelUpdate.created_by;
            //data.created_at = modelUpdate.created_at;
            data.updated_by = modelUpdate.updated_by;
            data.updated_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }

        public LawsEntity Delete(Guid id)
        {
            var data = _context.laws.Find(id);

            data.deleted_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }  
    }
}
<file_sep>/Data/DataContext.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Todo.Models;

namespace Core.Data
{
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options){}

        public DbSet<StaffEntity> staff { get; set; }
        public DbSet<LawsEntity> laws { get; set; }
        public DbSet<UserEntity> user { get; set; }
        public DbSet<RoleEntity> role { get; set; }
        public DbSet<PermissionEntity> permission { get; set; }
        public DbSet<StaffHasRoleEntity> staff_has_role { get; set; }
        public DbSet<RoleHasPermissionEntity> role_has_permission { get; set; }

    }
}
<file_sep>/Models/Permission/IStaffHasRole.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Todo.Models;

namespace Project_bkk_api.Models.Permission
{
    public interface IStaffHasRole
    {
        List<StaffHasRoleEntity> GetAll();
        StaffHasRoleEntity GetById(Guid id);
        StaffHasRoleViewModel Create(StaffHasRoleViewModel model);
        //StaffHasRoleEntity Update(Guid id, StaffHasRoleEntity modelUpdate);
        StaffHasRoleEntity Delete(Guid id);
    }
}
<file_sep>/Controllers/RoleController.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Project_bkk_api.Models;
using Microsoft.Extensions.Logging;
using Core.Data;
using Todo.Models;
using Project_bkk_api.Models.Permission;

namespace Project_bkk_api.Controllers
{
    [Route("api/Role")]
    public class RoleController : Controller
    {
        private ILogger<RoleController> _logger;

        private readonly IRole _role;

        public RoleController(IRole role)
        {
            _role = role;
        }

        /// <summary>
        /// Role get all data
        /// </summary>
        /// <remarks>
        /// Role get all data
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns all data</response>
        /// <response code="500">Error Occurred</response>  
        [HttpGet("")]
        [ProducesResponseType(typeof(List<RoleEntity>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetAll()
        {
            try
            {
                var data = _role.GetAll();
                return Json(data);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Role get By Id
        /// </summary>
        /// <remarks>
        /// Role get By Id
        /// </remarks>
        /// <returns>Return all data</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpGet("GetById")]
        [ProducesResponseType(typeof(List<RoleEntity>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult GetById(Guid id)
        {
            try
            {
                var data = _role.GetById(id);
                return Json(data);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Role create item
        /// </summary>
        /// <remarks>
        /// Role create item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpPost]
        [ProducesResponseType(typeof(List<RoleEntity>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Create([FromBody] RoleEntity model)
        {
            try
            {
                if (model != null)
                {
                    _role.Create(model);
                }
                return Json(model);
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Role Update item
        /// </summary>
        /// <remarks>
        /// Role Update item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpPut("{id}")]
        [ProducesResponseType(typeof(List<RoleEntity>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Update(Guid id, [FromBody] RoleEntity model)
        {
            try
            {
                if (id == null)
                {
                    return StatusCode(400, $"ID is not valid.");
                }
                else
                {
                    var res = _role.Update(id, model);
                    return Json(res);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }

        /// <summary>
        /// Role Update item
        /// </summary>
        /// <remarks>
        /// Role Update item
        /// </remarks>
        /// <returns>Return create item</returns>
        /// <response code="200">Returns the item</response>
        /// <response code="500">Error Occurred</response>  
        [HttpDelete("{id}")]
        [ProducesResponseType(typeof(List<RoleEntity>), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(500)]
        public IActionResult Delete(Guid id)
        {
            try
            {
                if (id == null)
                {
                    return StatusCode(400, $"ID is not valid.");
                }
                else
                {
                    var res = _role.Delete(id);
                    return Json(res);
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Exception while get list of items.", ex);
                return StatusCode(500, $"Exception while get list of items. {ex.Message}");
            }
        }
    }
}
<file_sep>/Models/User/UserRepository.cs
﻿using Core.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Project_bkk_api.Models.User;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class UserRepository : IUser
    {
        private DataContext _context;

        private IConfiguration configuration;

        public UserRepository(DataContext context, IConfiguration iConfig)
        {
            _context = context;
            configuration = iConfig;
        }

        public List<UserEntity> GetAll()
        {
            return _context.user.Where(x => x.deleted_at == null).ToList();
        }

        public UserEntity GetById(Guid id)
        {
            return _context.user.Find(id);
        }

        public UserReturnViewModel GetByIdViaJWT(string authHeader)
        {
            var handler = new JwtSecurityTokenHandler();
            string[] auth = authHeader.Split(" ");

            var exp = handler.ReadJwtToken(auth[1]).Payload.Exp;

            DateTime now = DateTime.Now;
            var date = now;

            var lifeTime = new JwtSecurityTokenHandler().ReadToken(auth[1]).ValidTo.ToLocalTime();

            var id = handler.ReadJwtToken(auth[1]).Payload.Jti;
            var user = _context.user.Find(Guid.Parse(id));
            var data = new UserReturnViewModel();
            data.id = user.id;
            data.firstname = user.firstname;
            data.lastname = user.lastname;
            data.username = user.username;
            data.full_company_name = user.full_company_name;
            data.type = user.type;
            data.email = user.email;

            return data;
        }

        public UserEntity Create(UserEntity model)
        {

            var user = _context.user.Where(x => x.username == model.username || x.email == model.email).FirstOrDefault();

            if(user == null)
            {
                model.id = Guid.NewGuid();
                model.deleted_at = null;
                model.password = <PASSWORD>MD5(model.password);
                _context.user.Add(model);
                _context.SaveChanges();

                model.password = null;
                return model;
            }
            else
            {
                if (user.username == model.username)
                {
                    throw new Exception("Username already exists");
                } else if (user.email == model.email)
                {
                    throw new Exception("Email already exists");
                }
                else
                {
                    throw new Exception("Username and Email already exists");
                }
                
            } 
        }

        public object Login(UserLoginViewModel model)
        {
            var checkPassword = <PASSWORD>ToMD5(model.password);
            var user = _context.user.Where(x => x.username == model.username && x.password == checkPassword).FirstOrDefault();

            if (user == null)
            {
                throw new Exception();
            }
            else
            {
                var claims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Jti, user.id.ToString())
                    //new Claim(JwtRegisteredClaimNames.NameId, user.username),
                    //new Claim(JwtRegisteredClaimNames.GivenName, user.firstname),
                    //new Claim(JwtRegisteredClaimNames.FamilyName, user.lastname),
                    //new Claim(JwtRegisteredClaimNames.Email, user.email)
                };
                string key = configuration.GetSection("JWT").GetSection("SecurityKey").Value;
                var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));

                var token = new JwtSecurityToken(
                    expires: DateTime.Now.AddSeconds(5),
                    claims: claims,
                    signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
                    );

                var return_token = new {
                    jwt_token = new JwtSecurityTokenHandler().WriteToken(token),
                };

                return return_token;
            }   
        }

        static string StringToMD5(string value)
        {
            using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
            {
                UTF8Encoding utf8 = new UTF8Encoding();
                byte[] data = md5.ComputeHash(utf8.GetBytes(value));
                return Convert.ToBase64String(data);
            }
        }

        public UserEntity Update(Guid id, UserEntity modelUpdate)
        {
            var data = _context.user.Find(id);

            data.firstname = modelUpdate.firstname;
            data.lastname = modelUpdate.lastname;
            data.is_active = modelUpdate.is_active;
            //data.created_by = modelUpdate.created_by;
            //data.created_at = modelUpdate.created_at;
            data.updated_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }

        public UserEntity Delete(Guid id)
        {
            var data = _context.user.Find(id);

            data.deleted_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }  
    }
}
<file_sep>/Models/Permission/StaffHasRoleRepository.cs
﻿using Core.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Project_bkk_api.Models.Permission;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class StaffHasRoleRepository : IStaffHasRole
    {
        private DataContext _context;

        private IConfiguration configuration;

        public StaffHasRoleRepository(DataContext context, IConfiguration iConfig)
        {
            _context = context;
            configuration = iConfig;
        }

        public List<StaffHasRoleEntity> GetAll()
        {
            return _context.staff_has_role.Where(x => x.deleted_at == null).ToList();
        }

        public StaffHasRoleEntity GetById(Guid id)
        {
            return _context.staff_has_role.Find(id);
        }

        public StaffHasRoleViewModel Create(StaffHasRoleViewModel model)
        {
            var shrEn = new StaffHasRoleEntity();
            shrEn.id = Guid.NewGuid();
            shrEn.role_id = model.role_id;
            shrEn.staff_id = model.staff_id;
            shrEn.is_active = model.is_active;
            shrEn.created_by = model.created_by;
            shrEn.created_at = model.created_at;
            shrEn.updated_at = model.updated_at;
            shrEn.updated_by = model.updated_by;
            
            _context.staff_has_role.Add(shrEn);
            _context.SaveChanges();

            model.id = shrEn.id;
            return model;
        }

        //public StaffHasRoleEntity Update(Guid id, StaffHasRoleEntity modelUpdate)
        //{
        //    var data = _context.staff_has_role.Find(id);

        //    //data.created_by = modelUpdate.created_by;
        //    //data.created_at = modelUpdate.created_at;
        //    data.updated_at = DateTime.Now;

        //    _context.SaveChanges();

        //    return data;
        //}

        public StaffHasRoleEntity Delete(Guid id)
        {
            var data = _context.staff_has_role.Find(id);

            data.deleted_at = DateTime.Now;

            _context.SaveChanges();

            return data;
        }  
    }
}
<file_sep>/Models/Staff/StaffViewModel.cs
﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Todo.Models
{
    public class StaffViewModel
    {
        public Guid id { get; set; }

        public string firstname { get; set; }

        public string lastname { get; set; }

        public string position { get; set; }

        public string username { get; set; }

        public string password { get; set; }

        public string email { get; set; }

        public string tel { get; set; }

        public bool is_active { get; set; }

        public Guid? created_by { get; set; }

        public DateTime? created_at { get; set; }

        public Guid? updated_by { get; set; }

        public DateTime? updated_at { get; set; }

        public DateTime? deleted_at { get; set; }

    }
}
<file_sep>/Models/User/IUser.cs
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Todo.Models;

namespace Project_bkk_api.Models.User
{
    public interface IUser
    {
        List<UserEntity> GetAll();
        UserEntity GetById(Guid id);
        UserReturnViewModel GetByIdViaJWT(string authHeader);
        UserEntity Create(UserEntity model);
        UserEntity Update(Guid id, UserEntity modelUpdate);
        UserEntity Delete(Guid id);
        object Login(UserLoginViewModel model);
    }
}
