Advertisement
Guest User

TwoStepAut

a guest
Jun 24th, 2018
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.70 KB | None | 0 0
  1. ===================================================Program=============================================================================
  2. class Program {
  3.         static string ReadPassword() {
  4.             StringBuilder sb = new StringBuilder();
  5.             ConsoleKeyInfo key;
  6.             do {
  7.                 key = Console.ReadKey(true);
  8.                 if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter && key.Key != ConsoleKey.Escape) {
  9.                     sb.Append(key.KeyChar);
  10.                     Console.Write("*");
  11.                 }
  12.                 else {
  13.                     if (key.Key == ConsoleKey.Backspace && sb.Length > 0) {
  14.                         sb.Remove(sb.Length - 1, 1);
  15.                         Console.Write("\b \b");
  16.                     }
  17.                 }
  18.             } while (key.Key != ConsoleKey.Enter);
  19.             Console.WriteLine();
  20.             return sb.ToString();
  21.         }
  22.  
  23.         static void Main(string[] args) {
  24.             Console.Write("Enter username: ");
  25.             var username = Console.ReadLine();
  26.             Console.Write("Enter password: ");
  27.             var password = ReadPassword();
  28.  
  29.             var authenticator = new Authenticator();
  30.             if (authenticator.CheckFirstStep(username, password)) {
  31.                 Console.WriteLine("Enter confirmation code: ");
  32.                 var code = Console.ReadLine();
  33.                 if (authenticator.CheckSecondStep(username, code))
  34.                     Console.WriteLine("Success!!!");
  35.                 else
  36.                     Console.WriteLine("Invalid confirmation code");
  37.             }
  38.             else {
  39.                 Console.WriteLine("Incorrect username / password");
  40.             }
  41.             Console.ReadKey();
  42.         }
  43.     }
  44. ======================================================================================================================================================================================SmsConfirmationChannel==================================================================
  45. class SmsConfirmationChannel : IConfirmationChannel {
  46.         public void SendConfirmationCode(User user, string code) {
  47.             // Just a placeholder function
  48.             Console.WriteLine($"SMS on {user.Telephone}: Your confirmation code is {code}");
  49.         }
  50.     }
  51. =======================================================================================================================================
  52. ==============================================User=====================================================================================
  53.  public class User {
  54.         public int Id { get; set; }
  55.         public string Username { get; set; }
  56.         public string PasswordHash { get; set; }
  57.         public string Email { get; set; }
  58.         public string Telephone { get; set; }
  59.         public string Code { get; set; }
  60.         public DateTime CodeGenerationDt { get; set; }
  61.     }
  62. =======================================================================================================================================
  63. ============================================UserRepository=============================================================================
  64. class UserRepository : IDisposable {
  65.         private Context _context = new Context();
  66.  
  67.         public IQueryable<User> Users {
  68.             get {
  69.                 return _context.Users;
  70.             }
  71.         }
  72.  
  73.         public void UpdateConfirmationCode(User user, string code) {
  74.             user.Code = code;
  75.             user.CodeGenerationDt = DateTime.Now;
  76.             _context.SaveChanges();
  77.         }
  78.  
  79.         public void Dispose() {
  80.             _context.Dispose();
  81.         }
  82.     }
  83. ====================================================================================================================================================================================IConfirmationChannel======================================================================
  84. public interface IConfirmationChannel {
  85.         void SendConfirmationCode(User user, string code);
  86.     }
  87. ====================================================================================================================================================================================Helpers===================================================================================
  88. static class Helpers {
  89.         private static Random r = new Random();
  90.  
  91.         public static string GetHash(string password) {
  92.             var md5 = MD5.Create();
  93.             var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
  94.             return Convert.ToBase64String(hash);
  95.         }
  96.        
  97.         public static string GenerateConfirmationCode(int length) {
  98.             var sb = new StringBuilder();
  99.             for (int i = 0; i < length; i++) {
  100.                 sb.Append((char)('0' + r.Next(10)));
  101.             }
  102.             return sb.ToString();
  103.         }
  104.     }
  105. ======================================================================================================================================================================================Factory=================================================================================
  106. class Factory {
  107.         private static Factory _default;
  108.  
  109.         public static Factory Default {
  110.             get {
  111.                 return _default ?? (_default = new Factory());
  112.             }
  113.         }
  114.  
  115.         private Factory() {
  116.  
  117.         }
  118.  
  119.         public IConfirmationChannel CreateConfirmationChannel() {
  120.             return new EmailConfirmationChannel();
  121.         }
  122.     }
  123. ==============================================================================================================================================================================================EmailConfirmationChannel========================================================
  124. class EmailConfirmationChannel : IConfirmationChannel {
  125.         public void SendConfirmationCode(User user, string code) {
  126.             // Just a placeholder function
  127.             Console.WriteLine($"New e-mail on {user.Email}: Your confirmation code is {code}");
  128.         }
  129.     }
  130. ==============================================================================================================================================================================================Context=========================================================================
  131. class Context : DbContext {
  132.         public DbSet<User> Users { get; set; }
  133.  
  134.         public Context() : base("UserDB") {
  135.  
  136.         }
  137.     }
  138. =======================================================================================================================================
  139. ======================================================Authenticator====================================================================
  140. public class Authenticator {
  141.         private const int CodeLength = 6;
  142.  
  143.         IConfirmationChannel _confirmationChannel = Factory.Default.CreateConfirmationChannel();
  144.  
  145.         public bool CheckFirstStep(string username, string password) {
  146.             // Compare username and password with the ones stored in the internal container
  147.             var passwordHash = Helpers.GetHash(password);
  148.             using (var repo = new UserRepository()) {
  149.                 var user = repo.Users.FirstOrDefault(u => u.Username == username && u.PasswordHash == passwordHash);
  150.                 if (user != null) {
  151.                     var code = Helpers.GenerateConfirmationCode(CodeLength);
  152.                     repo.UpdateConfirmationCode(user, code);
  153.                     _confirmationChannel.SendConfirmationCode(user, code);
  154.                     return true;
  155.                 }
  156.                 else
  157.                     return false;
  158.             }
  159.         }
  160.  
  161.         public bool CheckSecondStep(string username, string code) {
  162.             using (var repo = new UserRepository()) {
  163.                 var user = repo.Users.FirstOrDefault(u => u.Username == username && u.Code == code);
  164.                 if (user != null && user.CodeGenerationDt.AddMinutes(2) > DateTime.Now)
  165.                     return true;
  166.                 else
  167.                     return false;
  168.             }
  169.         }
  170.     }
  171. =======================================================================================================================================
  172. =========================================================Configuration=================================================================
  173. using System;
  174.     using System.Data.Entity;
  175.     using System.Data.Entity.Migrations;
  176.     using System.Linq;
  177.  
  178.     internal sealed class Configuration : DbMigrationsConfiguration<TwoStepAuth.Context>
  179.     {
  180.         public Configuration()
  181.         {
  182.             AutomaticMigrationsEnabled = false;
  183.         }
  184.  
  185.         protected override void Seed(TwoStepAuth.Context context)
  186.         {
  187.             //  This method will be called after migrating to the latest version.
  188.  
  189.             // CodeGenerationDt has to be filled or it can be made nullable
  190.             // (DateTime?)
  191.  
  192.             context.Users.AddOrUpdate(u => u.Username,
  193.                 new User
  194.                 {
  195.                     Username = "ivan",
  196.                     PasswordHash = Helpers.GetHash("ivanpass"),
  197.                     Telephone = "+79101112233",
  198.                     Email = "ivan@yandex.ru",
  199.                     CodeGenerationDt = new DateTime(2000, 1, 1)
  200.                 },
  201.                 new User
  202.                 {
  203.                     Username = "petya",
  204.                     PasswordHash = Helpers.GetHash("petyapass"),
  205.                     Telephone = "+79102221144",
  206.                     Email = "petya@yandex.ru",
  207.                     CodeGenerationDt = new DateTime(2000, 1, 1)
  208.                 }
  209.              );
  210.         }
  211.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement