chatr/ChatrServer/Chatr/Account.cs

167 lines
4.3 KiB
C#

using System.Globalization;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System;
namespace Tesses.Chatr.Server
{
public class Account
{
public Account()
{
Name="";
Username="";
HashedPassword="";
Salt="";
Email="";
ShowUserNameToAnyBody=false;
ShowBots=true;
HiddenBots=new List<long>();
HiddenUsers=new List<long>();
IsAnonymous=false;
IsAdmin=false;
}
public bool IsHidden(long user,long bot)
{
if(bot != -1 && !ShowBots) return true;
if(HiddenUsers.Contains(user)) return true;
if(bot == -1) return false;
if(HiddenBots.Contains(bot)) return true;
return false;
}
public bool IsAnonymous {get;set;}
public long Id {get;set;}
public string Name {get;set;}
public string Username {get;set;}
public string Email {get;set;}
public string HashedPassword {get;set;}
public string Salt {get;set;}
public bool Verified {get;set;}
public bool ShowUserNameToAnyBody {get;set;}
public bool ShowBots {get;set;}
public List<long> HiddenUsers {get;set;}
public List<long> HiddenBots {get;set;}
public bool IsAdmin { get; internal set; }
public bool IsValid()
{
if(!IsValidEmail(Email)) return false;
if(!IsValidUserName(Username)) return false;
if(!IsValidName(Name)) return false;
return true;
}
public static bool IsValidName(string name)
{
foreach(var c in name)
{
if(c == ' ') continue;
if(char.IsLetterOrDigit(c)) continue;
if(c=='_') continue;
return false;
}
return true;
}
public static bool IsValidUserName(string username)
{
if(string.IsNullOrWhiteSpace(username)) return false;
if(username.Contains(" ")) return false;
return IsValidName(username);
}
private static bool IsValidEmail(string email)
{
if (string.IsNullOrWhiteSpace(email))
return false;
try
{
// Normalize the domain
email = Regex.Replace(email, @"(@)(.+)$", DomainMapper,
RegexOptions.None, TimeSpan.FromMilliseconds(200));
// Examines the domain part of the email and normalizes it.
string DomainMapper(Match match)
{
// Use IdnMapping class to convert Unicode domain names.
var idn = new IdnMapping();
// Pull out and process domain name (throws ArgumentException on invalid)
string domainName = idn.GetAscii(match.Groups[2].Value);
return match.Groups[1].Value + domainName;
}
}
catch (RegexMatchTimeoutException e)
{
_=e;
return false;
}
catch (ArgumentException e)
{
_=e;
return false;
}
try
{
return Regex.IsMatch(email,
@"^[^@\s]+@[^@\s]+\.[^@\s]+$",
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
public bool IsCorrectPassword(string password)
{
string pass = $"{password}{Salt}";
using(SHA256 mySHA256 = SHA256.Create())
{
string check= Convert.ToBase64String(mySHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(pass)));
return check.Equals(HashedPassword);
}
}
public void SetPassword(string password,bool resetSalt=true)
{
if(resetSalt) Salt=GetNewSalt();
string pass = $"{password}{Salt}";
using(SHA256 mySHA256 = SHA256.Create())
{
string check= Convert.ToBase64String(mySHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(pass)));
HashedPassword=check;
}
}
public static string GetNewSalt()
{
return Session.GetNewId();
}
}
}