Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ===================================================Program=============================================================================
- class Program {
- static string ReadPassword() {
- StringBuilder sb = new StringBuilder();
- ConsoleKeyInfo key;
- do {
- key = Console.ReadKey(true);
- if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter && key.Key != ConsoleKey.Escape) {
- sb.Append(key.KeyChar);
- Console.Write("*");
- }
- else {
- if (key.Key == ConsoleKey.Backspace && sb.Length > 0) {
- sb.Remove(sb.Length - 1, 1);
- Console.Write("\b \b");
- }
- }
- } while (key.Key != ConsoleKey.Enter);
- Console.WriteLine();
- return sb.ToString();
- }
- static void Main(string[] args) {
- Console.Write("Enter username: ");
- var username = Console.ReadLine();
- Console.Write("Enter password: ");
- var password = ReadPassword();
- var authenticator = new Authenticator();
- if (authenticator.CheckFirstStep(username, password)) {
- Console.WriteLine("Enter confirmation code: ");
- var code = Console.ReadLine();
- if (authenticator.CheckSecondStep(username, code))
- Console.WriteLine("Success!!!");
- else
- Console.WriteLine("Invalid confirmation code");
- }
- else {
- Console.WriteLine("Incorrect username / password");
- }
- Console.ReadKey();
- }
- }
- ======================================================================================================================================================================================SmsConfirmationChannel==================================================================
- class SmsConfirmationChannel : IConfirmationChannel {
- public void SendConfirmationCode(User user, string code) {
- // Just a placeholder function
- Console.WriteLine($"SMS on {user.Telephone}: Your confirmation code is {code}");
- }
- }
- =======================================================================================================================================
- ==============================================User=====================================================================================
- public class User {
- public int Id { get; set; }
- public string Username { get; set; }
- public string PasswordHash { get; set; }
- public string Email { get; set; }
- public string Telephone { get; set; }
- public string Code { get; set; }
- public DateTime CodeGenerationDt { get; set; }
- }
- =======================================================================================================================================
- ============================================UserRepository=============================================================================
- class UserRepository : IDisposable {
- private Context _context = new Context();
- public IQueryable<User> Users {
- get {
- return _context.Users;
- }
- }
- public void UpdateConfirmationCode(User user, string code) {
- user.Code = code;
- user.CodeGenerationDt = DateTime.Now;
- _context.SaveChanges();
- }
- public void Dispose() {
- _context.Dispose();
- }
- }
- ====================================================================================================================================================================================IConfirmationChannel======================================================================
- public interface IConfirmationChannel {
- void SendConfirmationCode(User user, string code);
- }
- ====================================================================================================================================================================================Helpers===================================================================================
- static class Helpers {
- private static Random r = new Random();
- public static string GetHash(string password) {
- var md5 = MD5.Create();
- var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
- return Convert.ToBase64String(hash);
- }
- public static string GenerateConfirmationCode(int length) {
- var sb = new StringBuilder();
- for (int i = 0; i < length; i++) {
- sb.Append((char)('0' + r.Next(10)));
- }
- return sb.ToString();
- }
- }
- ======================================================================================================================================================================================Factory=================================================================================
- class Factory {
- private static Factory _default;
- public static Factory Default {
- get {
- return _default ?? (_default = new Factory());
- }
- }
- private Factory() {
- }
- public IConfirmationChannel CreateConfirmationChannel() {
- return new EmailConfirmationChannel();
- }
- }
- ==============================================================================================================================================================================================EmailConfirmationChannel========================================================
- class EmailConfirmationChannel : IConfirmationChannel {
- public void SendConfirmationCode(User user, string code) {
- // Just a placeholder function
- Console.WriteLine($"New e-mail on {user.Email}: Your confirmation code is {code}");
- }
- }
- ==============================================================================================================================================================================================Context=========================================================================
- class Context : DbContext {
- public DbSet<User> Users { get; set; }
- public Context() : base("UserDB") {
- }
- }
- =======================================================================================================================================
- ======================================================Authenticator====================================================================
- public class Authenticator {
- private const int CodeLength = 6;
- IConfirmationChannel _confirmationChannel = Factory.Default.CreateConfirmationChannel();
- public bool CheckFirstStep(string username, string password) {
- // Compare username and password with the ones stored in the internal container
- var passwordHash = Helpers.GetHash(password);
- using (var repo = new UserRepository()) {
- var user = repo.Users.FirstOrDefault(u => u.Username == username && u.PasswordHash == passwordHash);
- if (user != null) {
- var code = Helpers.GenerateConfirmationCode(CodeLength);
- repo.UpdateConfirmationCode(user, code);
- _confirmationChannel.SendConfirmationCode(user, code);
- return true;
- }
- else
- return false;
- }
- }
- public bool CheckSecondStep(string username, string code) {
- using (var repo = new UserRepository()) {
- var user = repo.Users.FirstOrDefault(u => u.Username == username && u.Code == code);
- if (user != null && user.CodeGenerationDt.AddMinutes(2) > DateTime.Now)
- return true;
- else
- return false;
- }
- }
- }
- =======================================================================================================================================
- =========================================================Configuration=================================================================
- using System;
- using System.Data.Entity;
- using System.Data.Entity.Migrations;
- using System.Linq;
- internal sealed class Configuration : DbMigrationsConfiguration<TwoStepAuth.Context>
- {
- public Configuration()
- {
- AutomaticMigrationsEnabled = false;
- }
- protected override void Seed(TwoStepAuth.Context context)
- {
- // This method will be called after migrating to the latest version.
- // CodeGenerationDt has to be filled or it can be made nullable
- // (DateTime?)
- context.Users.AddOrUpdate(u => u.Username,
- new User
- {
- Username = "ivan",
- PasswordHash = Helpers.GetHash("ivanpass"),
- Telephone = "+79101112233",
- Email = "ivan@yandex.ru",
- CodeGenerationDt = new DateTime(2000, 1, 1)
- },
- new User
- {
- Username = "petya",
- PasswordHash = Helpers.GetHash("petyapass"),
- Telephone = "+79102221144",
- Email = "petya@yandex.ru",
- CodeGenerationDt = new DateTime(2000, 1, 1)
- }
- );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement