using BookManagementProgram.XtraForm;
using BookManagementProgram.Model;
using BookManagementProgram.Repository;
using System;
using System.Windows.Forms;
using DevExpress.XtraTabbedMdi;
using System.Reflection;
using BookManagementProgram.UserControls;
namespace BookManagementProgram
{
public partial class Main : DevExpress.XtraEditors.XtraForm
{
User user = BookUserRepository.user;
XtraTabbedMdiManager mdiManager;
public Main()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
switch(user.authorityNo)
{
case 0:
user_page.Visible = true;
book_page.Visible = true;
rental_page.Visible = true;
break;
case 1:
book_page.Visible = true;
rental_page.Visible = true;
break;
case 2:
rental_page.Visible = true;
break;
}
}
// 폼 종료
private void Main_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
// 폼 종료 버튼
private void home_close_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Application.Exit();
}
// 비밀번호 변경 버튼
private void home_changePassword_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
(new FindByPassword()).ShowDialog();
}
// 메인 폼 로드
private void Main_Load(object sender, EventArgs e)
{
ChildFormAdd();
Home();
}
// MID Child Form추가
private void ChildFormAdd()
{
mdiManager = new XtraTabbedMdiManager();
mdiManager.MdiParent = this;
mdiManager.HeaderButtons = DevExpress.XtraTab.TabButtons.Close;
mdiManager.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Top;
mdiManager.PageAdded += MdiManager_ChildFormAdd;
mdiManager.ClosePageButtonShowMode = DevExpress.XtraTab.ClosePageButtonShowMode.InActiveTabPageAndTabControlHeader;
}
// MDI 설정
private void MdiManager_ChildFormAdd(object sender, MdiTabPageEventArgs e)
{
XtraMdiTabPage page = e.Page;
}
// 첫 로드할때 보여줄 메인 페이지
private void Home()
{
foreach (Form item in this.MdiChildren)
{
if (item.Name == "HOME") //Notice
{
item.Focus();
return;
}
}
Assembly asm = Assembly.GetExecutingAssembly();
Form frm = (Form)asm.CreateInstance(string.Format("{0}.{1}", "BookManagementProgram.MainControls", "MainPageForm"));
if (frm != null)
{
frm.Text = "메인화면";
frm.MdiParent = this;
frm.Dock = DockStyle.Fill;
frm.Show();
}
}
// 유저 페이지 유저 조회 버튼
private void user_reset_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
MenuRun("UserSelectForm", user_reset_btn.Hint);
}
// 메뉴 아이템에 따라 MID Child 생성
private void MenuRun(string Menu, string FormTitle)
{
string nameSpace;
foreach (Form item in this.MdiChildren)
{
if (Menu == item.Name)
{
item.Close();
}
}
Form frm = null;
if (Menu.Equals("UserSelectForm"))
{
nameSpace = "BookManagementProgram.UserControls";
System.Reflection.Assembly assembly = System.Reflection.Assembly.Load("BookManagementProgram");
string FileName = "UserSelectForm";
frm = (Form)assembly.CreateInstance(string.Format("{0}.{1}", nameSpace, FileName));
}
if (frm != null)
{
frm.Text = FormTitle;
frm.MdiParent = this;
frm.Show();
}
else
{
MessageBox.Show("개발중이거나 존재하지 않는 화면입니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
// 유저 페이지 유저 등록 버튼
private void user_add_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
(new UserAddForm()).ShowDialog();
}
// 유저 페이지 유저 검색 버튼
private void user_search_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
(new UserSearchForm()).ShowDialog();
}
}
}
using BookManagementProgram.Repository;
using DevExpress.XtraGrid.Views.Grid;
using System.Windows.Forms;
namespace BookManagementProgram.UserControls
{
public partial class UserSelectForm : Form
{
BookUserRepository userRepository = null;
public UserSelectForm()
{
InitializeComponent();
userRepository = new BookUserRepository();
InitGridControl();
this.gridControl1.DataSource = userRepository.GetAllUsers();
}
private void InitGridControl()
{
GridView gv = this.gridControl1.MainView as GridView;
gv.OptionsView.ShowGroupPanel = false;
gv.OptionsBehavior.Editable = false;
}
}
}
using BookManagementProgram.Model;
using System.Collections.Generic;
using System.Data;
namespace BookManagementProgram.Repository
{
interface IBookUserRepository
{
string Login(string userId, string userPw);
string FindById(string userNo, string userName);
bool FindByPassword(string userNo, string userId, string newPassword);
bool InsertLoginLog();
DataTable GetAllUsers();
Dictionary<string, object> GetAuthList();
Dictionary<string, object> GetGradeList();
bool AddUser(User user);
User GetUserByNumber(string userNo);
bool DeleteUserByNumber(string userNo);
bool UpdateUserInfo(User user);
}
}
using BookManagementProgram.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
namespace BookManagementProgram.Repository
{
class BookUserRepository : IBookUserRepository
{
private SqlConnection conn = null;
private SqlCommand cmd = null;
public static List<User> userList = null;
public static User user = null;
public BookUserRepository()
{
conn = DBConn.DBConn.getConn();
cmd = new SqlCommand();
cmd.Connection = conn;
}
// 로그인 로직
public string Login(string userId, string userPw)
{
try
{
string sql = $"EXEC BOOK_LOGIN_S1 @USER_ID = '{userId}', @USER_PW = '{Encryption(userPw)}';";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while (SR.Read())
{
user = new User(
SR[0].ToString()
, SR[1].ToString()
, SR[2].ToString()
, SR[3].ToString()
, SR[4].ToString()
, SR[5].ToString()
, SR[6].ToString()
, (int)SR[7]
, (int)SR[8]
);
}
SR.Close();
}
return user.userNo;
}
catch(SqlException e)
{
return e.Message;
}
finally
{
conn.Close();
}
}
// 아이디 찾기 로직
public string FindById(string userNo, string userName)
{
try
{
string sql = $"EXEC BOOK_LOGIN_S2 @USER_NO = {userNo}, @USER_NAME = '{userName}';";
string user_id = string.Empty;
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while (SR.Read())
{
user_id = SR[0].ToString();
}
SR.Close();
}
return $"아이디 : {user_id} 입니다.";
}
catch (SqlException e)
{
return e.Message;
}
finally
{
conn.Close();
}
}
// 비밀번호 찾기 로직
public bool FindByPassword(string userNo, string userId, string newPassword)
{
try
{
string sql = $"EXEC BOOK_LOGIN_U1 @USER_NO = {userNo}, @USER_ID = '{userId}', @NEW_PW = '{Encryption(newPassword)}';";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 로그 입력
public bool InsertLoginLog()
{
try
{
string sql = $"EXEC BOOK_LOGIN_I1 @USER_NO = {user.userNo}, @USER_ID = '{user.userId}', @ENTER_IP = '{GetExternalIPAddress()}';";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 사용자 전체 리스트
public DataTable GetAllUsers()
{
DataTable dt = new DataTable();
try
{
string sql = "EXEC BOOK_LOGIN_S3;";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
dt.Load(SR);
}
return dt;
}
catch (SqlException e)
{
return dt;
}
finally
{
conn.Close();
}
}
// 권한 리스트
public Dictionary<string, object> GetAuthList()
{
Dictionary<string, object> dic = new Dictionary<string, object>();
try
{
string sql = "EXEC BOOK_LOGIN_S4;";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while(SR.Read())
{
dic.Add(SR[1].ToString(), (int)SR[0]);
}
}
return dic;
}
catch (SqlException e)
{
return dic;
}
finally
{
conn.Close();
}
}
// 등급 리스트
public Dictionary<string, object> GetGradeList()
{
Dictionary<string, object> dic = new Dictionary<string, object>();
try
{
string sql = "EXEC BOOK_LOGIN_S5;";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while (SR.Read())
{
dic.Add(SR[1].ToString(), (int)SR[0]);
}
}
return dic;
}
catch (SqlException e)
{
return dic;
}
finally
{
conn.Close();
}
}
// 사용자 등록
public bool AddUser(User user)
{
try
{
string pw = Encryption(user.userPw);
string sql = $"EXEC BOOK_LOGIN_I2 @USER_NAME = '{user.userName}', @USER_ADDR = '{user.userAddress}', @USER_BIRTH='{user.userBirth}', @USER_ID='{user.userId}', @USER_PW='{pw}', @USER_AUTH={user.authorityNo}, @USER_GRADE={user.gradeNo};";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 유저 조회
public User GetUserByNumber(string userNo)
{
User user = new User();
try
{
string sql = $"EXEC BOOK_LOGIN_S6 @USER_NO = {userNo};";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
SR.Read();
user.userNo = SR[0].ToString();
user.userName = SR[1].ToString();
user.userAddress = SR[2].ToString();
user.userBirth = SR[3].ToString();
user.userId = SR[4].ToString();
user.userPw = SR[5].ToString();
user.registerDate = SR[6].ToString();
user.deregisterDate = SR[7].ToString();
user.authorityNo = (int)SR[8];
user.gradeNo = (int)SR[9];
}
return user;
}
catch (SqlException e)
{
return user;
}
finally
{
conn.Close();
}
}
// 사용자 삭제
public bool DeleteUserByNumber(string userNo)
{
try
{
string sql = $"EXEC BOOK_LOGIN_D1 @USER_NO = {userNo};";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 사용자 정보 수정
public bool UpdateUserInfo(User user)
{
try
{
string sql = $"EXEC BOOK_LOGIN_U2 @USER_NO = {user.userNo}, @USER_NAME = '{user.userName}', @USER_ADDR = '{user.userAddress}', @USER_BIRTH = '{user.userBirth}', @USER_ID = '{user.userId}', @AUTH_NO = {user.authorityNo}, @GRADE_NO = {user.gradeNo};";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// SHA256 암호화 메서드
public static string Encryption(string data)
{
SHA256 sha = new SHA256Managed();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data));
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in hash)
{
stringBuilder.AppendFormat("{0:x2}", b);
}
return stringBuilder.ToString();
}
// 외부 IP
public static string GetExternalIPAddress()
{
string externalip = new WebClient().DownloadString("http://ipinfo.io/ip").Trim();
return externalip ?? GetInternalIPAddress();//null경우 내부 IP 반환;
}
// 내부
// DNS, 단순 도메인 이름 확인 기능이 제공
// GetGostEntity, 호스트 이름 또는 IP 주소를 IPHostEntry 인스턴스로 확인
// GetHostName, 로컬 컴퓨터의 호스트 이름을 가져온다
public static string GetInternalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("인터넷 연결 없음");
}
}
}
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_S3] Script Date: 2021-08-20 오후 7:10:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08.20>
-- Description: <도서관리프로그램, 전체 사용자 조회>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_S3]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT l.user_no as '사용자번호', i.user_name as '사용자이름', i.user_address as '사용자주소', CONVERT(char(10), i.user_birth, 102) as '생년월일'
, l.user_id as '아이디', l.user_pw as '비밀번호' , l.register_date as '가입일', l.deregister_date as '탈퇴일'
, a.authority_name as '권한', g.grade_name as '등급'
FROM Book_User_LogIn as l
INNER JOIN Book_User_Info as i
ON l.user_no = i.user_no
INNER JOIN Book_User_Auth as a
ON l.authority_no = a.authority_no
INNER JOIN Book_User_Grade as g
ON l.grade_no = g.grade_no
ORDER BY l.user_no;
END
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookManagementProgram.Model
{
class User
{
private string user_no;
private string user_name;
private string user_address;
private string user_birth;
private string user_id;
private string user_pw;
private string register_date;
private string deregister_date;
private int authority_no;
private string authority_name;
private int grade_no;
private string grade_name;
public string userNo { get { return user_no; } set { user_no = value; } }
public string userName { get { return user_name; } set { user_name = value; } }
public string userAddress { get { return user_address; } set { user_address = value; } }
public string userBirth { get { return user_birth; } set { user_birth = value; } }
public string userId { get { return user_id; } set { user_id = value; } }
public string userPw { get { return user_pw; } set { user_pw = value; } }
public string registerDate { get { return register_date; } set { register_date = value; } }
public string deregisterDate { get { return deregister_date; } set { deregister_date = value; } }
public int authorityNo { get { return authority_no; } set { authority_no = value; } }
public string authorityName { get { return authority_name; } set { authority_name = value; } }
public int gradeNo { get { return grade_no; } set { grade_no = value; } }
public string gradeName { get { return grade_name; } set { grade_name = value; } }
// 로그인 시 사용되는 생성자
public User(string user_no, string user_name, string user_address, string user_birth, string user_id, string user_pw, string register_date, int authority_no, int grade_no)
{
this.user_no = user_no;
this.user_name = user_name;
this.user_address = user_address;
this.user_birth = user_birth;
this.user_id = user_id;
this.user_pw = user_pw;
this.register_date = register_date;
this.authority_no = authority_no;
this.grade_no = grade_no;
}
// 전체 사용자 조회때 사용되는 생성자
public User(string user_no, string user_name, string user_address, string user_birth, string user_id, string user_pw, string register_date, string deregister_date, string authority_name, string grade_name)
{
this.user_no = user_no;
this.user_name = user_name;
this.user_address = user_address;
this.user_birth = user_birth;
this.user_id = user_id;
this.user_pw = user_pw;
this.register_date = register_date;
this.deregister_date = deregister_date;
this.authority_name = authority_name;
this.grade_name = grade_name;
}
public User()
{
}
}
}
using BookManagementProgram.Model;
using BookManagementProgram.Repository;
using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
namespace BookManagementProgram.UserControls
{
public partial class UserAddForm : Form
{
BookUserRepository userRepository = null;
private int _duration = 0; // 타이머 라벨에 표시할 숫자 변수
private string _auth_code = ""; // 인증번호
public UserAddForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterParent;
userRepository = new BookUserRepository();
// 권한 콤보 박스 초기화
user_auth_cmb.DataSource = new BindingSource(userRepository.GetAuthList(), null);
user_auth_cmb.DisplayMember = "Key";
user_auth_cmb.ValueMember = "Value";
// 등급 콤보박스 초기화
user_grade_cmb.DataSource = new BindingSource(userRepository.GetGradeList(), null);
user_grade_cmb.DisplayMember = "Key";
user_grade_cmb.ValueMember = "Value";
}
// 취소버튼
private void cancel_btn_Click(object sender, EventArgs e)
{
this.Close();
}
// 인증번호 전송 버튼
private void auth_btn_Click(object sender, EventArgs e)
{
if (CheckInput())
{
TwiloRun();
}
}
// 인증번호 확인
private void auth_check_btn_Click(object sender, EventArgs e)
{
if(auth_number_txt.Text == _auth_code)
{
ResetTimerAndCode();
MessageBox.Show("인증에 성공하였습니다.");
add_user_btn.Enabled = true;
return;
}
MessageBox.Show("다시 확인해주세요.");
auth_number_txt.Focus();
}
// 사용자 등록
private void add_user_btn_Click(object sender, EventArgs e)
{
if(userRepository.AddUser(CreateUserInstance()))
{
MessageBox.Show("사용자 등록에 성공하였습니다.");
this.Close();
return;
}
MessageBox.Show("사용자 등록에 실패했습니다.");
}
private User CreateUserInstance()
{
User user = new User();
user.userName = user_name_txt.Text;
user.userAddress = user_address_txt.Text;
user.userBirth = user_birth_txt.Text;
user.userId = user_id_txt.Text;
user.userPw = user_password_txt.Text;
user.authorityNo = (int)user_auth_cmb.SelectedValue;
user.gradeNo = (int)user_grade_cmb.SelectedValue;
return user;
}
// 텍스트박스 입력 확인
private bool CheckInput()
{
bool check = false;
if (string.IsNullOrEmpty(user_name_txt.Text))
{
MessageBox.Show("성함을 입력해주세요.");
user_name_txt.Focus();
}
else if (string.IsNullOrEmpty(user_address_txt.Text))
{
MessageBox.Show("주소를 입력해주세요.");
user_address_txt.Focus();
}
else if (string.IsNullOrEmpty(user_birth_txt.Text) || CheckBirthPattern(user_birth_txt.Text))
{
MessageBox.Show("생년월일을 입력해주세요.(2021.01.01)");
user_birth_txt.Focus();
}
else if (string.IsNullOrEmpty(user_id_txt.Text))
{
MessageBox.Show("아아디를 입력해주세요.");
user_id_txt.Focus();
}
else if (string.IsNullOrEmpty(user_password_txt.Text))
{
MessageBox.Show("비밀번호를 입력해주세요.");
user_password_txt.Focus();
}
else if (string.IsNullOrEmpty(user_phone_txt.Text) || CheckPhonePattern(user_phone_txt.Text))
{
MessageBox.Show("휴대폰번호를 입력해주세요.(01012341234)");
user_address_txt.Focus();
}
else
{
check = true;
}
return check;
}
// 생년월일 확인 정규식
private bool CheckBirthPattern(string birth)
{
string pattern = @"^(19[0-9][0-9]|20\d{2})\.(0[0-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])$";
if (!Regex.IsMatch(birth, pattern))
{
return true;
}
else
{
return false;
}
}
// 휴대폰번호 정규식
private bool CheckPhonePattern(string phone)
{
string pattern = @"^\d{3}\d{3,4}\d{4}$";
if (!Regex.IsMatch(phone, pattern))
{
return true;
}
else
{
return false;
}
}
// Twiolog
private async void TwiloRun()
{
string phone = user_phone_txt.Text;
// 타이머 초기화 및 인증번호 생성
_duration = 60;
_auth_code = GetRandomCode();
timer1.Stop();
timer1 = new Timer();
timer1.Tick += new EventHandler(CountDown);
timer1.Interval = 1000;
timer1.Start();
await Task.Run(() => SpendSMSTwilo(phone));
}
private void SpendSMSTwilo(string phone)
{
// twilo
try
{
string accountSid = Properties.Settings.Default.TwiloSID;
string authToken = Properties.Settings.Default.TwiloToken;
TwilioClient.Init(accountSid, authToken);
var message = MessageResource.Create(
body: $"인증번호 : {_auth_code}",
from: new Twilio.Types.PhoneNumber(Properties.Settings.Default.TwiloHost),
to: new Twilio.Types.PhoneNumber($"+82{phone}")
);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
// 타이머 카운트 다운
private void CountDown(object sender, EventArgs e)
{
if (_duration == 0 || _duration < 0)
{
ResetTimerAndCode();
MessageBox.Show("인증 시간이 초과되었습니다.");
return;
}
_duration--;
timer_lbl.Text = _duration.ToString();
}
// 랜덤 코드 생성
private string GetRandomCode()
{
Random rand = new Random();
string input = "abcdefghijklmnopqrstuvxyz0123456789";
var chars = Enumerable.Range(0, 6).Select(x => input[rand.Next(0, input.Length)]);
return new string(chars.ToArray());
}
// 타이머 및 코드 초기화
private void ResetTimerAndCode()
{
timer1.Stop();
timer1.Dispose();
_auth_code = "";
}
}
}
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_S4] Script Date: 2021-08-20 오후 6:57:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08.20>
-- Description: <도서관리프로그램, 권한 조회>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_S4]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM Book_User_Auth;
END
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_S5] Script Date: 2021-08-20 오후 6:58:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08-20>
-- Description: <도서관리프로그램, 등급 조회>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_S5]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM Book_User_Grade;
END
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_I2] Script Date: 2021-08-20 오후 6:58:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08.20>
-- Description: <도서관리프로그램, 사용자 등록>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_I2]
@USER_NAME NVARCHAR(20)
,@USER_ADDR NVARCHAR(50)
,@USER_BIRTH DATETIME
,@USER_ID NVARCHAR(20)
,@USER_PW NVARCHAR(20)
,@USER_AUTH INT
,@USER_GRADE INT
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
INSERT INTO Book_User_Info(user_name, user_address, user_birth) VALUES(@USER_NAME, @USER_ADDR, @USER_BIRTH);
INSERT INTO Book_User_LogIn(user_id, user_pw, register_date, authority_no, grade_no) VALUES(@USER_ID, CONVERT(varbinary(256), @USER_PW), GETDATE(), @USER_AUTH, @USER_GRADE); -- admin
END
UserSearchForm 생성자
user_select_btn_Click
reset_btn_Click
user_delete_btn_Click
user_update_btn_Click
using BookManagementProgram.Model;
using BookManagementProgram.Repository;
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace BookManagementProgram.UserControls
{
public partial class UserSearchForm : Form
{
BookUserRepository userRepository = null;
public UserSearchForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterParent;
userRepository = new BookUserRepository();
user_auth_cmb.DataSource = new BindingSource(userRepository.GetAuthList(), null);
user_auth_cmb.DisplayMember = "Key";
user_auth_cmb.ValueMember = "Value";
user_grade_cmb.DataSource = new BindingSource(userRepository.GetGradeList(), null);
user_grade_cmb.DisplayMember = "Key";
user_grade_cmb.ValueMember = "Value";
}
// 취소버튼
private void cancel_btn_Click(object sender, EventArgs e)
{
this.Close();
}
// 유저 조회 버튼
private void user_select_btn_Click(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(user_no_txt.Text))
{
MessageBox.Show("사용자 번호를 입력해주세요.");
user_no_txt.Focus();
return;
}
User user = userRepository.GetUserByNumber(user_no_txt.Text);
if(user == null)
{
MessageBox.Show("사용자 번호를 확인해주세요!");
user_no_txt.Focus();
return;
}
user_no_txt.ReadOnly = true;
user_name_txt.Text = user.userName;
user_address_txt.Text = user.userAddress;
user_birth_txt.Text = user.userBirth;
user_id_txt.Text = user.userId;
user_registerdate_txt.Text = user.registerDate;
user_deregisterdate_txt.Text = user.deregisterDate;
user_auth_cmb.SelectedValue = user.authorityNo;
user_grade_cmb.SelectedValue = user.gradeNo;
}
// 초기화 버튼
private void reset_btn_Click(object sender, EventArgs e)
{
user_no_txt.ReadOnly = false;
user_name_txt.Text = string.Empty;
user_address_txt.Text = string.Empty;
user_birth_txt.Text = string.Empty;
user_id_txt.Text = string.Empty;
user_registerdate_txt.Text = string.Empty;
user_deregisterdate_txt.Text = string.Empty;
user_auth_cmb.SelectedIndex = 0;
user_grade_cmb.SelectedIndex = 0;
}
// 유저 삭제 버튼
private void user_delete_btn_Click(object sender, EventArgs e)
{
if (!user_no_txt.ReadOnly)
{
MessageBox.Show("사용자 조회를 하고 수정해주세요.");
}
if (MessageBox.Show($"{user_no_txt.Text}번의 사용자를 정말 삭제하시겠습니까?", null, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
if(userRepository.DeleteUserByNumber(user_no_txt.Text))
{
MessageBox.Show("정상적으로 삭제 되었습니다.");
this.Close();
return;
}
MessageBox.Show("없는 사용자 이거나 번호를 확인해주세요.");
return;
}
MessageBox.Show("취소 하셨습니다.");
}
// 유저 수정 버튼
private void user_update_btn_Click(object sender, EventArgs e)
{
if(!user_no_txt.ReadOnly)
{
MessageBox.Show("사용자 조회를 하고 수정해주세요.");
}
if(string.IsNullOrEmpty(user_no_txt.Text))
{
MessageBox.Show("사용자 번호를 입력해주세요.");
user_no_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_name_txt.Text))
{
MessageBox.Show("사용자 이름을 입력해주세요.");
user_name_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_address_txt.Text))
{
MessageBox.Show("사용자 주소를 입력해주세요.");
user_address_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_birth_txt.Text) || CheckBirthPattern(user_birth_txt.Text))
{
MessageBox.Show("생년월일을 입력해주세요.");
user_birth_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_id_txt.Text))
{
MessageBox.Show("아이디를 입력해주세요.");
user_id_txt.Focus();
return;
}
if (MessageBox.Show($"{user_no_txt.Text}번의 사용자를 수정하시겠습니까?", null, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
User user = new User();
user.userNo = user_no_txt.Text;
user.userName = user_name_txt.Text;
user.userAddress = user_address_txt.Text;
user.userBirth = user_birth_txt.Text;
user.userId = user_id_txt.Text;
user.authorityNo = (int)user_auth_cmb.SelectedValue;
user.gradeNo = (int)user_grade_cmb.SelectedValue;
if (userRepository.UpdateUserInfo(user))
{
MessageBox.Show("정상적으로 수정 되었습니다.");
this.Close();
return;
}
MessageBox.Show("없는 사용자 이거나 번호를 확인해주세요.");
return;
}
MessageBox.Show("취소 하셨습니다.");
}
// 생년월일 확인 정규식
private bool CheckBirthPattern(string birth)
{
string pattern = @"^(19[0-9][0-9]|20\d{2})\.(0[0-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])$";
if (!Regex.IsMatch(birth, pattern))
{
return true;
}
else
{
return false;
}
}
}
}
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_S6] Script Date: 2021-08-20 오후 7:42:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08.20>
-- Description: <도서관리 프로그램, 사용자번호로 사용자 조회>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_S6]
@USER_NO INT
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT l.user_no, i.user_name, i.user_address, CONVERT(char(10), i.user_birth, 102), l.user_id, l.user_pw, l.register_date, l.deregister_date, a.authority_no, g.grade_no
FROM Book_User_LogIn as l
INNER JOIN Book_User_Info as i
ON l.user_no = i.user_no
INNER JOIN Book_User_Auth as a
ON l.authority_no = a.authority_no
INNER JOIN Book_User_Grade as g
ON l.grade_no = g.grade_no
WHERE l.user_no = @USER_NO;
END
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_D1] Script Date: 2021-08-20 오후 7:40:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08.20>
-- Description: <도서관리프로그램, 사용자 삭제>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_D1]
@USER_NO INT
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DELETE FROM Book_User_LogIn WHERE user_no = @USER_NO;
DELETE FROM Book_User_Info WHERE user_no = @USER_NO;
END
USE [BookManagement]
GO
/****** Object: StoredProcedure [dbo].[BOOK_LOGIN_U2] Script Date: 2021-08-20 오후 7:40:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <문민승>
-- Create date: <2021.08.20>
-- Description: <도서관리프로그램, 사용자 정보 수정>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_U2]
@USER_NO INT
,@USER_NAME NVARCHAR(20)
,@USER_ADDR NVARCHAR(50)
,@USER_BIRTH NVARCHAR(20)
,@USER_ID NVARCHAR(20)
,@AUTH_NO INT
,@GRADE_NO INT
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
UPDATE Book_User_Info
SET user_name = @USER_NAME
,user_address = @USER_ADDR
,user_birth = @USER_BIRTH
WHERE user_no = @USER_NO;
IF(@AUTH_NO = 3)
UPDATE Book_User_LogIn
SET user_id = @USER_ID
,authority_no = @AUTH_NO
,grade_no = @GRADE_NO
,deregister_date = GETDATE()
WHERE user_no = @USER_NO;
ELSE
UPDATE Book_User_LogIn
SET user_id = @USER_ID
,authority_no = @AUTH_NO
,grade_no = @GRADE_NO
,deregister_date = NULL
WHERE user_no = @USER_NO;
END
using BookManagementProgram.Model;
using BookManagementProgram.Repository;
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace BookManagementProgram.UserControls
{
public partial class UserSearchForm : Form
{
BookUserRepository userRepository = null;
public UserSearchForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterParent;
userRepository = new BookUserRepository();
user_auth_cmb.DataSource = new BindingSource(userRepository.GetAuthList(), null);
user_auth_cmb.DisplayMember = "Key";
user_auth_cmb.ValueMember = "Value";
user_grade_cmb.DataSource = new BindingSource(userRepository.GetGradeList(), null);
user_grade_cmb.DisplayMember = "Key";
user_grade_cmb.ValueMember = "Value";
}
// 취소버튼
private void cancel_btn_Click(object sender, EventArgs e)
{
this.Close();
}
// 유저 조회 버튼
private void user_select_btn_Click(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(user_no_txt.Text))
{
MessageBox.Show("사용자 번호를 입력해주세요.");
user_no_txt.Focus();
return;
}
User user = userRepository.GetUserByNumber(user_no_txt.Text);
if(user == null)
{
MessageBox.Show("사용자 번호를 확인해주세요!");
user_no_txt.Focus();
return;
}
user_no_txt.ReadOnly = true;
user_name_txt.Text = user.userName;
user_address_txt.Text = user.userAddress;
user_birth_txt.Text = user.userBirth;
user_id_txt.Text = user.userId;
user_registerdate_txt.Text = user.registerDate;
user_deregisterdate_txt.Text = user.deregisterDate;
user_auth_cmb.SelectedValue = user.authorityNo;
user_grade_cmb.SelectedValue = user.gradeNo;
}
// 초기화 버튼
private void reset_btn_Click(object sender, EventArgs e)
{
user_no_txt.ReadOnly = false;
user_name_txt.Text = string.Empty;
user_address_txt.Text = string.Empty;
user_birth_txt.Text = string.Empty;
user_id_txt.Text = string.Empty;
user_registerdate_txt.Text = string.Empty;
user_deregisterdate_txt.Text = string.Empty;
user_auth_cmb.SelectedIndex = 0;
user_grade_cmb.SelectedIndex = 0;
}
// 유저 삭제 버튼
private void user_delete_btn_Click(object sender, EventArgs e)
{
if (!user_no_txt.ReadOnly)
{
MessageBox.Show("사용자 조회를 하고 삭제해주세요.");
return;
}
if (MessageBox.Show($"{user_no_txt.Text}번의 사용자를 정말 삭제하시겠습니까?", null, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
if(userRepository.DeleteUserByNumber(user_no_txt.Text))
{
MessageBox.Show("정상적으로 삭제 되었습니다.");
this.Close();
return;
}
MessageBox.Show("없는 사용자 이거나 번호를 확인해주세요.");
return;
}
MessageBox.Show("취소 하셨습니다.");
}
// 유저 수정 버튼
private void user_update_btn_Click(object sender, EventArgs e)
{
if(!user_no_txt.ReadOnly)
{
MessageBox.Show("사용자 조회를 하고 수정해주세요.");
return;
}
if(string.IsNullOrEmpty(user_no_txt.Text))
{
MessageBox.Show("사용자 번호를 입력해주세요.");
user_no_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_name_txt.Text))
{
MessageBox.Show("사용자 이름을 입력해주세요.");
user_name_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_address_txt.Text))
{
MessageBox.Show("사용자 주소를 입력해주세요.");
user_address_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_birth_txt.Text) || CheckBirthPattern(user_birth_txt.Text))
{
MessageBox.Show("생년월일을 입력해주세요.");
user_birth_txt.Focus();
return;
}
if (string.IsNullOrEmpty(user_id_txt.Text))
{
MessageBox.Show("아이디를 입력해주세요.");
user_id_txt.Focus();
return;
}
if (MessageBox.Show($"{user_no_txt.Text}번의 사용자를 수정하시겠습니까?", null, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
User user = new User();
user.userNo = user_no_txt.Text;
user.userName = user_name_txt.Text;
user.userAddress = user_address_txt.Text;
user.userBirth = user_birth_txt.Text;
user.userId = user_id_txt.Text;
user.authorityNo = (int)user_auth_cmb.SelectedValue;
user.gradeNo = (int)user_grade_cmb.SelectedValue;
if (userRepository.UpdateUserInfo(user))
{
MessageBox.Show("정상적으로 수정 되었습니다.");
this.Close();
return;
}
MessageBox.Show("없는 사용자 이거나 번호를 확인해주세요.");
return;
}
MessageBox.Show("취소 하셨습니다.");
}
// 생년월일 확인 정규식
private bool CheckBirthPattern(string birth)
{
string pattern = @"^(19[0-9][0-9]|20\d{2})\.(0[0-9]|1[0-2])\.(0[1-9]|[1-2][0-9]|3[0-1])$";
if (!Regex.IsMatch(birth, pattern))
{
return true;
}
else
{
return false;
}
}
}
}
using BookManagementProgram.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
namespace BookManagementProgram.Repository
{
class BookUserRepository : IBookUserRepository
{
private SqlConnection conn = null;
private SqlCommand cmd = null;
public static List<User> userList = null;
public static User user = null;
public BookUserRepository()
{
conn = DBConn.DBConn.getConn();
cmd = new SqlCommand();
cmd.Connection = conn;
}
// 로그인 로직
public string Login(string userId, string userPw)
{
try
{
string sql = $"EXEC BOOK_LOGIN_S1 @USER_ID = '{userId}', @USER_PW = '{Encryption(userPw)}';";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while (SR.Read())
{
user = new User(
SR[0].ToString()
, SR[1].ToString()
, SR[2].ToString()
, SR[3].ToString()
, SR[4].ToString()
, SR[5].ToString()
, SR[6].ToString()
, (int)SR[7]
, (int)SR[8]
);
}
SR.Close();
}
return user.userNo;
}
catch(SqlException e)
{
return e.Message;
}
finally
{
conn.Close();
}
}
// 아이디 찾기 로직
public string FindById(string userNo, string userName)
{
try
{
string sql = $"EXEC BOOK_LOGIN_S2 @USER_NO = {userNo}, @USER_NAME = '{userName}';";
string user_id = string.Empty;
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while (SR.Read())
{
user_id = SR[0].ToString();
}
SR.Close();
}
return $"아이디 : {user_id} 입니다.";
}
catch (SqlException e)
{
return e.Message;
}
finally
{
conn.Close();
}
}
// 비밀번호 찾기 로직
public bool FindByPassword(string userNo, string userId, string newPassword)
{
try
{
string sql = $"EXEC BOOK_LOGIN_U1 @USER_NO = {userNo}, @USER_ID = '{userId}', @NEW_PW = '{Encryption(newPassword)}';";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 로그 입력
public bool InsertLoginLog()
{
try
{
string sql = $"EXEC BOOK_LOGIN_I1 @USER_NO = {user.userNo}, @USER_ID = '{user.userId}', @ENTER_IP = '{GetExternalIPAddress()}';";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 사용자 전체 리스트
public DataTable GetAllUsers()
{
DataTable dt = new DataTable();
try
{
string sql = "EXEC BOOK_LOGIN_S3;";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
dt.Load(SR);
}
return dt;
}
catch (SqlException e)
{
return dt;
}
finally
{
conn.Close();
}
}
// 권한 리스트
public Dictionary<string, object> GetAuthList()
{
Dictionary<string, object> dic = new Dictionary<string, object>();
try
{
string sql = "EXEC BOOK_LOGIN_S4;";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while(SR.Read())
{
dic.Add(SR[1].ToString(), (int)SR[0]);
}
}
return dic;
}
catch (SqlException e)
{
return dic;
}
finally
{
conn.Close();
}
}
// 등급 리스트
public Dictionary<string, object> GetGradeList()
{
Dictionary<string, object> dic = new Dictionary<string, object>();
try
{
string sql = "EXEC BOOK_LOGIN_S5;";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while (SR.Read())
{
dic.Add(SR[1].ToString(), (int)SR[0]);
}
}
return dic;
}
catch (SqlException e)
{
return dic;
}
finally
{
conn.Close();
}
}
// 사용자 등록
public bool AddUser(User user)
{
try
{
string pw = Encryption(user.userPw);
string sql = $"EXEC BOOK_LOGIN_I2 @USER_NAME = '{user.userName}', @USER_ADDR = '{user.userAddress}', @USER_BIRTH='{user.userBirth}', @USER_ID='{user.userId}', @USER_PW='{pw}', @USER_AUTH={user.authorityNo}, @USER_GRADE={user.gradeNo};";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 유저 조회
public User GetUserByNumber(string userNo)
{
User user = null;
try
{
string sql = $"EXEC BOOK_LOGIN_S6 @USER_NO = {userNo};";
cmd.CommandText = sql;
conn.Open();
// 데이터 출력
using (SqlDataReader SR = cmd.ExecuteReader())
{
while(SR.Read())
{
user = new User();
user.userNo = SR[0].ToString();
user.userName = SR[1].ToString();
user.userAddress = SR[2].ToString();
user.userBirth = SR[3].ToString();
user.userId = SR[4].ToString();
user.userPw = SR[5].ToString();
user.registerDate = SR[6].ToString();
user.deregisterDate = SR[7].ToString();
user.authorityNo = (int)SR[8];
user.gradeNo = (int)SR[9];
}
}
return user;
}
catch (SqlException e)
{
return user;
}
finally
{
conn.Close();
}
}
// 사용자 삭제
public bool DeleteUserByNumber(string userNo)
{
try
{
string sql = $"EXEC BOOK_LOGIN_D1 @USER_NO = {userNo};";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// 사용자 정보 수정
public bool UpdateUserInfo(User user)
{
try
{
string sql = $"EXEC BOOK_LOGIN_U2 @USER_NO = {user.userNo}, @USER_NAME = '{user.userName}', @USER_ADDR = '{user.userAddress}', @USER_BIRTH = '{user.userBirth}', @USER_ID = '{user.userId}', @AUTH_NO = {user.authorityNo}, @GRADE_NO = {user.gradeNo};";
cmd.CommandText = sql;
conn.Open();
return cmd.ExecuteNonQuery() > 0 ? true : false;
}
catch (SqlException e)
{
return false;
}
finally
{
conn.Close();
}
}
// SHA256 암호화 메서드
public static string Encryption(string data)
{
SHA256 sha = new SHA256Managed();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data));
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in hash)
{
stringBuilder.AppendFormat("{0:x2}", b);
}
return stringBuilder.ToString();
}
// 외부 IP
public static string GetExternalIPAddress()
{
string externalip = new WebClient().DownloadString("http://ipinfo.io/ip").Trim();
return externalip ?? GetInternalIPAddress();//null경우 내부 IP 반환;
}
// 내부
// DNS, 단순 도메인 이름 확인 기능이 제공
// GetGostEntity, 호스트 이름 또는 IP 주소를 IPHostEntry 인스턴스로 확인
// GetHostName, 로컬 컴퓨터의 호스트 이름을 가져온다
public static string GetInternalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("인터넷 연결 없음");
}
}
}