From e189735f2153efe16a7ea755fe0ed6858816797b Mon Sep 17 00:00:00 2001 From: zjoart Date: Wed, 8 Mar 2023 18:39:08 +0100 Subject: [PATCH] feat: completed all banking features --- sav_bank/App.config | 14 ++ sav_bank/Program.cs | 20 +++ sav_bank/Properties/AssemblyInfo.cs | 36 +++++ sav_bank/data/DataBase.cs | 99 ++++++++++++ sav_bank/model/AccountSummary.cs | 16 ++ sav_bank/model/Bank.cs | 101 ++++++++++++ sav_bank/model/Response.cs | 15 ++ sav_bank/model/SignUpDtos.cs | 19 +++ sav_bank/packages.config | 26 +++ sav_bank/presentation/AccountPresentation.cs | 111 +++++++++++++ sav_bank/presentation/LoginPresentation.cs | 54 +++++++ sav_bank/presentation/Presentaion.cs | 56 +++++++ .../presentation/RegistrationPresentation.cs | 70 ++++++++ sav_bank/sav_bank.csproj | 151 ++++++++++++++++++ sav_bank/sav_bank.sln | 25 +++ sav_bank/service/Account.cs | 81 ++++++++++ sav_bank/service/Login.cs | 36 +++++ sav_bank/service/Register.cs | 34 ++++ sav_bank/utils/PasswordHelper.cs | 61 +++++++ sav_bank/utils/SymbolWriter.cs | 18 +++ sav_bank/utils/VerifyInput.cs | 27 ++++ 21 files changed, 1070 insertions(+) create mode 100644 sav_bank/App.config create mode 100644 sav_bank/Program.cs create mode 100644 sav_bank/Properties/AssemblyInfo.cs create mode 100644 sav_bank/data/DataBase.cs create mode 100644 sav_bank/model/AccountSummary.cs create mode 100644 sav_bank/model/Bank.cs create mode 100644 sav_bank/model/Response.cs create mode 100644 sav_bank/model/SignUpDtos.cs create mode 100644 sav_bank/packages.config create mode 100644 sav_bank/presentation/AccountPresentation.cs create mode 100644 sav_bank/presentation/LoginPresentation.cs create mode 100644 sav_bank/presentation/Presentaion.cs create mode 100644 sav_bank/presentation/RegistrationPresentation.cs create mode 100644 sav_bank/sav_bank.csproj create mode 100644 sav_bank/sav_bank.sln create mode 100644 sav_bank/service/Account.cs create mode 100644 sav_bank/service/Login.cs create mode 100644 sav_bank/service/Register.cs create mode 100644 sav_bank/utils/PasswordHelper.cs create mode 100644 sav_bank/utils/SymbolWriter.cs create mode 100644 sav_bank/utils/VerifyInput.cs diff --git a/sav_bank/App.config b/sav_bank/App.config new file mode 100644 index 0000000..7d84477 --- /dev/null +++ b/sav_bank/App.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sav_bank/Program.cs b/sav_bank/Program.cs new file mode 100644 index 0000000..1d02048 --- /dev/null +++ b/sav_bank/Program.cs @@ -0,0 +1,20 @@ +using sav_bank.presentation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank +{ + internal class Program + { + + private const string storageFile = "bank.txt"; + static void Main(string[] args) + { + Console.WriteLine("Welcome to Sav Bank"); + Presentaion.Present(storageFile); + } + } +} diff --git a/sav_bank/Properties/AssemblyInfo.cs b/sav_bank/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cd04a92 --- /dev/null +++ b/sav_bank/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("sav_bank")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("sav_bank")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("04e34733-76c1-48c2-98b4-a267db477078")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/sav_bank/data/DataBase.cs b/sav_bank/data/DataBase.cs new file mode 100644 index 0000000..a8ae138 --- /dev/null +++ b/sav_bank/data/DataBase.cs @@ -0,0 +1,99 @@ +using sav_bank.model; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; + +namespace sav_bank.data +{ + public class DataBase + { + public static bool AddData(Bank model, string fileName) + { + try + { + var currentData = GetData(fileName); + currentData.Add(model); + + var options = new JsonSerializerOptions { WriteIndented = true }; + + string stringJson = JsonSerializer.Serialize(currentData, options: options); + File.WriteAllText(fileName, stringJson); + return true; + } + catch (System.Exception) + { + + return false; + } + + + } + + public static bool Update(Bank model, string fileName) + { + try + { + var currentData = GetData(fileName); + + var index = currentData.IndexOf(model); + currentData[index] =model; + + var options = new JsonSerializerOptions { WriteIndented = true }; + + string stringJson = JsonSerializer.Serialize(currentData, options: options); + File.WriteAllBytes(fileName, new byte[0]); + File.WriteAllText(fileName, stringJson); + return true; + } + catch (System.Exception) + { + return false; + } + + + } + + + public static List GetData(string fileName) + { + + try + { + string jsonString = File.ReadAllText(fileName); + List bank = JsonSerializer.Deserialize>(jsonString); + if (bank != null) + { + return bank; + } + + return new List(); + + } + catch (System.Exception) + { + + return new List(); + } + + } + + public static Bank GetDataByUserId(string userId, string fileName) + { + + var currentData = GetData(fileName); + if (currentData.Any()) + { + var userData = currentData.SingleOrDefault(x => x.UserName == userId); + + return userData; + } + else + { + + return null; + } + } + } +} diff --git a/sav_bank/model/AccountSummary.cs b/sav_bank/model/AccountSummary.cs new file mode 100644 index 0000000..54e5efb --- /dev/null +++ b/sav_bank/model/AccountSummary.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.model +{ + public class AccountSummary + { + public string Date { get; set; } + public bool IsDeposit { get; set; } + public string Amount { get; set; } + public string CurrentBalance { get; set; } + } +} diff --git a/sav_bank/model/Bank.cs b/sav_bank/model/Bank.cs new file mode 100644 index 0000000..9e0f6bb --- /dev/null +++ b/sav_bank/model/Bank.cs @@ -0,0 +1,101 @@ +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace sav_bank.model +{ + public class Bank : IEquatable + { + [JsonInclude] + public string UserId { get; private set; } + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + [JsonInclude] + public string AccountNumber { get; private set; } + public string Age { get; set; } + public string PhoneNumber { get; set; } + public byte[] PasswordHash { get; set; } + public byte[] PasswordSalt { get; set; } + [JsonInclude] + public decimal Balance { get; private set; } + public List AccountSummary { get; set; } + public Bank() + { + + } + + public Bank(string userName, string email, string phoneNumber, string firstName, string lastName, string age, byte[] passwordHash, byte[] passwordSalt) + { + UserId = PasswordHelper.GenerateUserId(); + AccountNumber = PasswordHelper.GenerateAccountNumber(); + UserName = userName; + Email = email; + Age = age; + FirstName = firstName; + LastName = lastName; + PhoneNumber = phoneNumber; + PasswordHash = passwordHash; + PasswordSalt = passwordSalt; + Balance = 0; + AccountSummary = new List(); + + } + + public bool Equals(Bank other) + { + if (this.AccountNumber != other.AccountNumber) return false; + if (this.UserId != other.UserId) return false; + + + return true; + } + + public decimal AddAcountBalance(decimal amount) + { + if(amount > 0) + { + + this.Balance += amount; + AddSummary(amount.ToString(), true); + return this.Balance; + } + else + { + return -1; + } + } + public decimal Withdraw(decimal amount) + { + if (amount > 0 && this.Balance > 0 && this.Balance > amount) + { + this.Balance = this.Balance - amount; + AddSummary(amount.ToString(), false); + return this.Balance; + } + else + { + return -1; + } + } + + private void AddSummary(string amount, bool isDeposit) + { + var summary = new AccountSummary() + { + Amount = amount, + Date = DateTime.Now.ToString(), + IsDeposit= isDeposit, + CurrentBalance = this.Balance.ToString(), + + }; + + AccountSummary.Add(summary); + } + } +} diff --git a/sav_bank/model/Response.cs b/sav_bank/model/Response.cs new file mode 100644 index 0000000..cfa60d6 --- /dev/null +++ b/sav_bank/model/Response.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.model +{ + public class BankResponse + { + public string Code { get; set; } + public string Description { get; set; } + public T Data { get; set; } + } +} diff --git a/sav_bank/model/SignUpDtos.cs b/sav_bank/model/SignUpDtos.cs new file mode 100644 index 0000000..437756f --- /dev/null +++ b/sav_bank/model/SignUpDtos.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank +{ + public class SignUpDtos + { + public string UserName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Age { get; set; } + public string PhoneNumber { get; set; } + public string Password { get; set; } + } +} diff --git a/sav_bank/packages.config b/sav_bank/packages.config new file mode 100644 index 0000000..b440707 --- /dev/null +++ b/sav_bank/packages.config @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sav_bank/presentation/AccountPresentation.cs b/sav_bank/presentation/AccountPresentation.cs new file mode 100644 index 0000000..2893775 --- /dev/null +++ b/sav_bank/presentation/AccountPresentation.cs @@ -0,0 +1,111 @@ +using sav_bank.model; +using sav_bank.service; +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.presentation +{ + public class AccountPresentation + { + + private static void WriteSumarry(AccountSummary summary) + { + Console.WriteLine("Deposit Date: {0}\n{1} Amount: N{2}\nCurrent balance: N{3}", summary.Date, summary.IsDeposit ? "Deposit" : "Withdrawal", summary.Amount, summary.CurrentBalance); + SymbolWriter.WriteSymbol(symbol: "$"); + } + public static void PresentAccount(in Bank user, string fileName) { + Console.WriteLine("Bank with us:"); + Console.WriteLine("Press 1 to VIEW ACCOUNT SUMMARY"); + Console.WriteLine("Press 2 to VIEW BALANCE"); + Console.WriteLine("Press 3 to DEPOSIT"); + Console.WriteLine("Press 4 to WITHDRAW"); + + Console.Write(">>>>> "); + var action = int.Parse(Console.ReadLine()); + + switch (action) + { + case 1: + var accountSummary = AccountService.GetAccountSummary(user.UserName, fileName); + if (accountSummary.Code.Equals("00")) + { + SymbolWriter.WriteSymbol(); + + foreach (var summary in accountSummary.Data) + WriteSumarry(summary); + SymbolWriter.WriteSymbol(); + } + else + { + Console.WriteLine(accountSummary.Description); + } + break; + case 2: + var accountBalance = AccountService.GetAccountBalance(user.UserName, fileName); + if (accountBalance.Code.Equals("00")) + { + Console.WriteLine("Account Balance: N{0}", accountBalance.Data); + } + else + { + Console.WriteLine(accountBalance.Description); + } + break; + case 3: + var deposit = AccountService.DepositAccount(user.UserName, fileName); + if (deposit.Code.Equals("00")) + { + Console.WriteLine("Account Balance: N{0}", deposit.Data); + } + else + { + Console.WriteLine(deposit.Description); + } + break; + case 4: + var withdraw = AccountService.Withdraw(user.UserName, fileName); + if (withdraw.Code.Equals("00")) + { + Console.WriteLine("Account Balance: N{0}", withdraw.Data); + } + else + { + Console.WriteLine(withdraw.Description); + } + break; + default: + Console.WriteLine("Input the correct value"); + break; + } + + Console.WriteLine("Do you want to perform another transaction"); + Console.WriteLine("............ Press 1 to continue"); + Console.WriteLine("............ Press 2 to quit"); + Console.Write(">>>>> "); + var anotherAction = int.Parse(Console.ReadLine()); + + while (anotherAction > 2) + { + Console.WriteLine("Please input the correct value."); + Console.Write(">>>>> "); + anotherAction = int.Parse(Console.ReadLine()); + } + + if (anotherAction == 1) + { + PresentAccount(in user, fileName); + } + else if (anotherAction == 2) + { + Console.WriteLine("Thank you for banking with us"); + + } + + SymbolWriter.WriteSymbol(); + } + } +} diff --git a/sav_bank/presentation/LoginPresentation.cs b/sav_bank/presentation/LoginPresentation.cs new file mode 100644 index 0000000..1bc4f62 --- /dev/null +++ b/sav_bank/presentation/LoginPresentation.cs @@ -0,0 +1,54 @@ +using sav_bank.model; +using sav_bank.service; +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.presentation +{ + public class LoginPresentation + { + public static Bank PresentLogin(string fileName) + + { + int attempt = 3; + string userName; + string password; + Console.WriteLine("To Login Enter your user name and Password"); + while(attempt != 0 ) + { + + Console.Write("Username: "); + userName = Console.ReadLine(); + Console.Write("Password: "); + password = Console.ReadLine(); + var login = LoginService.UserLogin(userName, password, fileName); + if (login.Code.Equals("00")) + { + + + SymbolWriter.WriteSymbol(); + Console.WriteLine(login.Data.UserName + " logged in successfully"); + SymbolWriter.WriteSymbol(); + + return login.Data; + + } + else + { + + attempt--; + Console.WriteLine("{0} , You have {1} attempts left",login.Description, attempt); + } + } + if(attempt == 0 ) + Console.WriteLine("You attempted more than 3 times account locked "); + Console.ReadKey(); + + return null; + } + } +} diff --git a/sav_bank/presentation/Presentaion.cs b/sav_bank/presentation/Presentaion.cs new file mode 100644 index 0000000..556f8ec --- /dev/null +++ b/sav_bank/presentation/Presentaion.cs @@ -0,0 +1,56 @@ +using sav_bank.model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.presentation +{ + public class Presentaion + { + public static void Present(string fileName) + { + string input; + + while (true) { + Console.WriteLine("To Login enter 1 to Register enter 2 :"); + input = Console.ReadLine(); + if(input.Equals("1") || input.Equals("2") ){ + break; + } + else + { + Console.WriteLine("You Entered an invalid value " + input); + } + + } + + Bank user = null; + bool registered = false; + + switch(input) + { + case "1": + user = LoginPresentation.PresentLogin(fileName); + break; + case "2": + registered = RegistrationPresentation.PresentRegister(fileName); + break; + default: + Console.WriteLine("Invalid"); + break; + } + + if(input == "1" && user != null) + { + AccountPresentation.PresentAccount(user, fileName); + Console.ReadKey(); + } + else if(input == "2" && registered) { Present(fileName); } + + + + } + } +} diff --git a/sav_bank/presentation/RegistrationPresentation.cs b/sav_bank/presentation/RegistrationPresentation.cs new file mode 100644 index 0000000..2b79ad9 --- /dev/null +++ b/sav_bank/presentation/RegistrationPresentation.cs @@ -0,0 +1,70 @@ +using sav_bank.service; +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.presentation +{ + public class RegistrationPresentation + { + public static bool PresentRegister(string fileName) { + Console.WriteLine("Fill in the following details to register"); + Console.Write("First Name: "); + string firstName = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(firstName); + Console.Write("Last Name: "); + string lastName = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(lastName); + Console.Write("Username: "); + string userName = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(userName); + Console.Write("Email: "); + string email = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(email); + Console.Write("Phone Number: "); + string phoneNumber = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(phoneNumber); + Console.Write("Age: "); + string age = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(age); + Console.Write("Password: "); + string password = Console.ReadLine(); + VerifyInput.VerifyEmptyOrNull(password); + + var dto = new SignUpDtos() + { + FirstName = firstName, + LastName = lastName, + UserName = userName, + Email = email, + PhoneNumber = phoneNumber, + Age = age, + Password = password, + + }; + + var signUp = RegisterService.RegisterUser(dto, fileName); + if (signUp.Code.Equals("00")) + { + + + SymbolWriter.WriteSymbol(); + Console.WriteLine("Account created successfully Procceed to login"); + SymbolWriter.WriteSymbol(); + + } + else + { + + Console.WriteLine(signUp.Description); + Console.WriteLine("Try again") + ; + PresentRegister(fileName); + } + return signUp.Data; + } + } +} diff --git a/sav_bank/sav_bank.csproj b/sav_bank/sav_bank.csproj new file mode 100644 index 0000000..d215711 --- /dev/null +++ b/sav_bank/sav_bank.csproj @@ -0,0 +1,151 @@ + + + + + Debug + AnyCPU + {04E34733-76C1-48C2-98B4-A267DB477078} + Exe + sav_bank + sav_bank + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + packages\Microsoft.Extensions.Configuration.7.0.0\lib\net462\Microsoft.Extensions.Configuration.dll + + + packages\Microsoft.Extensions.Configuration.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.Configuration.Abstractions.dll + + + packages\Microsoft.Extensions.Configuration.FileExtensions.7.0.0\lib\net462\Microsoft.Extensions.Configuration.FileExtensions.dll + + + packages\Microsoft.Extensions.Configuration.Json.7.0.0\lib\net462\Microsoft.Extensions.Configuration.Json.dll + + + packages\Microsoft.Extensions.DependencyInjection.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + packages\Microsoft.Extensions.FileProviders.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.FileProviders.Abstractions.dll + + + packages\Microsoft.Extensions.FileProviders.Physical.7.0.0\lib\net462\Microsoft.Extensions.FileProviders.Physical.dll + + + packages\Microsoft.Extensions.FileSystemGlobbing.7.0.0\lib\net462\Microsoft.Extensions.FileSystemGlobbing.dll + + + packages\Microsoft.Extensions.Primitives.7.0.0\lib\net462\Microsoft.Extensions.Primitives.dll + + + + packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + + packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + True + + + packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + True + True + + + packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll + True + True + + + packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll + + + packages\System.Text.Json.7.0.0\lib\net462\System.Text.Json.dll + + + packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sav_bank/sav_bank.sln b/sav_bank/sav_bank.sln new file mode 100644 index 0000000..4c737c9 --- /dev/null +++ b/sav_bank/sav_bank.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33205.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sav_bank", "sav_bank.csproj", "{04E34733-76C1-48C2-98B4-A267DB477078}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {04E34733-76C1-48C2-98B4-A267DB477078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04E34733-76C1-48C2-98B4-A267DB477078}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04E34733-76C1-48C2-98B4-A267DB477078}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04E34733-76C1-48C2-98B4-A267DB477078}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FD1A3EBF-FC05-427A-9CA9-D4C8F8DABA35} + EndGlobalSection +EndGlobal diff --git a/sav_bank/service/Account.cs b/sav_bank/service/Account.cs new file mode 100644 index 0000000..12b3833 --- /dev/null +++ b/sav_bank/service/Account.cs @@ -0,0 +1,81 @@ +using sav_bank.data; +using sav_bank.model; +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.service +{ + public class AccountService + { + + public static BankResponse GetAccountBalance(String userName, string fileName) + { + var user = DataBase.GetDataByUserId(userName, fileName); + if (user == null) + return new BankResponse() { Code = "25", Description = "User does not exist", Data = 0 }; + + Console.WriteLine(user.Balance); + + return new BankResponse() { Code = "00", Description = "Success", Data = user.Balance }; + + } + + public static BankResponse> GetAccountSummary(String userName, string fileName) + { + var user = DataBase.GetDataByUserId(userName, fileName); + if (user == null) + return new BankResponse> { Code = "25", Description = "User does not exist", Data = null }; + + if(user.AccountSummary == null || (user.AccountSummary != null && !user.AccountSummary.Any())) + return new BankResponse> { Code = "25", Description = "no records found", Data = null }; + + return new BankResponse> { Code = "00", Description = "Success", Data = user.AccountSummary }; + + } + public static BankResponse DepositAccount(String userName, string fileName) + { + Console.Write("Enter amount:"); + string input = Console.ReadLine(); + + VerifyInput.VerifyEmptyOrNull(input); + int amount = int.Parse(input); + var user = DataBase.GetDataByUserId(userName, fileName); + if (user == null) + return new BankResponse() { Code = "25", Description = "User does not exist", Data = 0 }; + + var updated = user.AddAcountBalance(amount); + if (updated == -1) + return new BankResponse() { Code = "25", Description = "Invalid amount", Data = 0 }; + + DataBase.Update(user, fileName); + return new BankResponse() { Code = "00", Description = "Success", Data = user.Balance }; + + } + public static BankResponse Withdraw(String userName, string fileName) + { + + Console.Write("Enter amount:"); + string input = Console.ReadLine(); + + VerifyInput.VerifyEmptyOrNull(input); + int amount = int.Parse(input); + + var user = DataBase.GetDataByUserId(userName, fileName); + if (user == null) + return new BankResponse() { Code = "25", Description = "User does not exist", Data = 0 }; + + var updated = user.Withdraw(amount); + if(updated == -1) + return new BankResponse() { Code = "25", Description = "Low balance", Data = 0 }; + + + DataBase.Update(user, fileName); + return new BankResponse() { Code = "00", Description = "Success", Data = user.Balance }; + + } + } +} diff --git a/sav_bank/service/Login.cs b/sav_bank/service/Login.cs new file mode 100644 index 0000000..87abe66 --- /dev/null +++ b/sav_bank/service/Login.cs @@ -0,0 +1,36 @@ +using sav_bank.data; +using sav_bank.model; +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.service +{ + public class LoginService + { + + + public static BankResponse UserLogin(string username, string password, string fileName) + { + + if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) + return new BankResponse() { Code = "25", Description = "Null Fields", Data = null }; + + + var user = DataBase.GetDataByUserId(username, fileName); + if (user == null) + return new BankResponse() { Code = "25", Description = "User does not exist", Data = null }; + + if (!PasswordHelper.VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt)) + return new BankResponse() { Code = "25", Description = "Incorrect Username or Password", Data = null }; + + + return new BankResponse() { Code = "00", Description = "Successfull", Data = user }; + + } + } +} diff --git a/sav_bank/service/Register.cs b/sav_bank/service/Register.cs new file mode 100644 index 0000000..388ce59 --- /dev/null +++ b/sav_bank/service/Register.cs @@ -0,0 +1,34 @@ +using sav_bank.data; +using sav_bank.model; +using sav_bank.utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.service +{ + public class RegisterService + { + public static BankResponse RegisterUser(SignUpDtos dto, string fileName) { + + var user = DataBase.GetDataByUserId(dto.UserName, fileName); + if (user != null) + return new BankResponse() { Code = "25", Description = "Username exist Already", Data = false }; + + PasswordHelper.CreatePasswordHash(dto.Password, out byte[] passwordHash, out byte[] passwordSalt); + var bankModel = new Bank(userName: dto.UserName, phoneNumber: dto.PhoneNumber,firstName: dto.FirstName, lastName: dto.LastName, email: dto.Email, age: dto.Age, passwordSalt :passwordSalt, passwordHash: passwordHash) {}; + + var added = DataBase.AddData(bankModel, fileName); + if(!added) + return new BankResponse() { Code = "25", Description = "Error creating account please try again", Data = false }; + + + return new BankResponse() { Code = "00", Description = "Success", Data = true }; + + + + } + } +} diff --git a/sav_bank/utils/PasswordHelper.cs b/sav_bank/utils/PasswordHelper.cs new file mode 100644 index 0000000..b6085f7 --- /dev/null +++ b/sav_bank/utils/PasswordHelper.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.utils +{ + internal class PasswordHelper + { + public static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt) + { + if (password == null) throw new ArgumentNullException("password"); + if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password"); + + var hmac = new System.Security.Cryptography.HMACSHA512(); + passwordSalt = hmac.Key; + passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); + } + + public static bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt) + { + if (password == null) throw new ArgumentNullException("password"); + if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password"); + if (storedHash.Length != 64) throw new ArgumentException("Invalid length of password hash (64 bytes expected).", "passwordHash"); + if (storedSalt.Length != 128) throw new ArgumentException("Invalid length of password salt (128 bytes expected).", "passwordHash"); + + using (var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt)) + { + var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); + for (int i = 0; i < computedHash.Length; i++) + { + if (computedHash[i] != storedHash[i]) return false; + } + } + + return true; + } + public static string GenerateAccountNumber() + { + Random generator = new Random(); + string r = generator.Next(0, 1000000).ToString("D11"); + if (r.Distinct().Count() == 1) + { + r = GenerateAccountNumber(); + } + return r; + } + + public static string GenerateUserId() + { + Random generator = new Random(); + string r = generator.Next(0, 1000000).ToString("D5"); + if (r.Distinct().Count() == 1) + { + r = GenerateUserId(); + } + return r; + } + } +} diff --git a/sav_bank/utils/SymbolWriter.cs b/sav_bank/utils/SymbolWriter.cs new file mode 100644 index 0000000..5575c75 --- /dev/null +++ b/sav_bank/utils/SymbolWriter.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.utils +{ + public class SymbolWriter + { + public static void WriteSymbol(int length = 50, string symbol = "=") + { + for (var i = 0; i < length; i++) + Console.Write(symbol); + Console.WriteLine(""); + } + } +} diff --git a/sav_bank/utils/VerifyInput.cs b/sav_bank/utils/VerifyInput.cs new file mode 100644 index 0000000..45a4a99 --- /dev/null +++ b/sav_bank/utils/VerifyInput.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace sav_bank.utils +{ + public class VerifyInput + { + public static string VerifyEmptyOrNull(string input) + { + while ( + string.IsNullOrEmpty(input) + + ) + { + Console.WriteLine("Input must not be empty"); + Console.Write("Please input new value: "); + input = Console.ReadLine(); + } + + + return input; + } + } +}