public void GenerateBackups() { StringBuilder res = new StringBuilder(); for (int i = 0; i < 5; i++) { res.Append(ForumUtilities.GetRandomHex(8)).Append("|"); } Update(Builders <BsonDocument> .Update.Set(TFA_BACKUPS, res.ToString())); }
public SetupCode GenerateTFA() { TwoFactorAuthenticator tfao = new TwoFactorAuthenticator(); string ihex = ForumUtilities.GetRandomB64(6); SetupCode sc = tfao.GenerateSetupCode("Frenetic LLC", UserName, ihex, 300, 300, true); Update(Builders <BsonDocument> .Update.Set(TFA_INTERNAL, ihex)); GenerateBackups(); return(sc); }
public BsonDocument GenerateNewUser(string uname, string pw, string email) { uname = uname.ToLowerInvariant(); BsonDocument bd = CreateEmptyUserDocument(); bd[Account.USERNAME] = uname; bd[Account.PASSWORD] = ForumUtilities.Hash(pw, uname); bd[Account.EMAIL] = email; bd[Account.UID] = getIDFor(TF_USERS); bd[Account.ACTIVATION_CODE] = ForumUtilities.GetRandomHex(32); return(bd); }
public string GenerateSession() { string sess = ForumUtilities.GetRandomHex(32); FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(UID, UserID); UpdateDefinition <BsonDocument> ud = Builders <BsonDocument> .Update.AddToSet(WEBSESS_CODES, sess); FindOneAndUpdateOptions <BsonDocument> foauo = new FindOneAndUpdateOptions <BsonDocument>(); foauo.IsUpsert = true; UserBase.FindOneAndUpdate(fd, ud, foauo); return(sess); }
public string GenerateOneUseSess(string typ) { if (!IsValidSessType(typ)) { return(null); } string sess = ForumUtilities.GetRandomHex(32); FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(UID, UserID); UpdateDefinition <BsonDocument> ud = Builders <BsonDocument> .Update.Set(PREFIX_ONE_USE_SESS + typ, sess + "/" + DateTimeOffset.UtcNow.ToUnixTimeSeconds()); FindOneAndUpdateOptions <BsonDocument> foauo = new FindOneAndUpdateOptions <BsonDocument>(); foauo.IsUpsert = true; UserBase.FindOneAndUpdate(fd, ud, foauo); return(sess); }
public string GenerateSessMaster(string typ) { if (!IsValidSessType(typ)) { return(null); } string sess = ForumUtilities.GetRandomHex(32); FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(UID, UserID); UpdateDefinition <BsonDocument> ud = Builders <BsonDocument> .Update.AddToSet(PREFIX_SESS_MASTER + typ, sess); FindOneAndUpdateOptions <BsonDocument> foauo = new FindOneAndUpdateOptions <BsonDocument>(); foauo.IsUpsert = true; UserBase.FindOneAndUpdate(fd, ud, foauo); return(sess); }
public LoginResult CanLogin(string pw, string tfa, bool checkTFA = true) { BsonDocument acc = Projected(PASSWORD, BANNED, USES_TFA, ACCOUNT_TYPE); if (acc == null) { return(LoginResult.MISSING); } if (acc[ACCOUNT_TYPE].AsInt32 != AT_VALID) { return(LoginResult.NOT_COMPLETED_REGISTRATION); } if (acc[BANNED].AsBoolean) { return(LoginResult.BANNED); } string opass = acc[PASSWORD].AsString; string[] dat = opass.Split(':'); if (dat[0] == "v2") { string hash = ForumUtilities.HashV2(pw, UserName, dat[1]); byte[] b1 = ForumUtilities.Enc.GetBytes(hash); byte[] b2 = ForumUtilities.Enc.GetBytes(opass); if (!ForumUtilities.SlowEquals(b1, b2)) { return(LoginResult.BAD_PASSWORD); } } else { // TODO: Error log upload! "Invalid password for " + UserName + ": unrecognized version, they will be unable to login without a reset!" return(LoginResult.BAD_PASSWORD); } if (checkTFA && acc[USES_TFA].AsBoolean) { if (!CheckTFA(tfa)) { return(LoginResult.BAD_TFA); } } return(LoginResult.ALLOWED); }
public void InstallDefaultUser(string pw) { IMongoCollection <BsonDocument> userbase = Database.GetCollection <BsonDocument>(TF_USERS); BsonDocument user = CreateEmptyUserDocument(); user[Account.UID] = (long)0; user[Account.USERNAME] = "admin"; user[Account.DISPLAY_NAME] = "Administrator"; user[Account.PASSWORD] = ForumUtilities.Hash(pw, "admin"); user[Account.ACTIVE] = true; user[Account.ACCOUNT_TYPE] = Account.AT_VALID; FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(Account.UID, (long)0); UpdateOptions uo = new UpdateOptions() { IsUpsert = true }; userbase.ReplaceOneAsync(fd, user, uo).Wait(); }
public LoginResult AttemptLogin(string username, string password, string tfa) { Account acc = Database.GetAccount(username); if (acc == null) { return(LoginResult.MISSING); } LoginResult res = acc.CanLogin(password, tfa); if (res != LoginResult.ALLOWED) { return(res); } acc.Update(Builders <BsonDocument> .Update.Set(Account.LAST_LOGIN_DATE, ForumUtilities.DateNow())); CookieOptions co_uid = new CookieOptions(); co_uid.HttpOnly = true; // NOTE: Microsoft HttpOnly documentation appears to be backwards? co_uid.Expires = DateTimeOffset.Now.AddYears(1); Response.Cookies.Append("session_uid", acc.UserID.ToString(), co_uid); Response.Cookies.Append("session_val", acc.GenerateSession(), co_uid); return(LoginResult.ALLOWED); }
public BsonDocument CreateEmptyUserDocument() { BsonDocument user = new BsonDocument(); user[Account.UID] = (long)-1; user[Account.USERNAME] = "example"; user[Account.PASSWORD] = "This Won't Be Usable"; user[Account.EMAIL] = "*****@*****.**"; user[Account.DISPLAY_NAME] = "Example"; user[Account.BANNED] = false; user[Account.BANNED_UNTIL] = ""; user[Account.BAN_REASON] = ""; user[Account.ACTIVE] = false; user[Account.ACTIVATION_CODE] = "<Unusable>?"; user[Account.REGISTER_DATE] = ForumUtilities.DateNow(); user[Account.LAST_LOGIN_DATE] = "Never"; user[Account.USES_TFA] = false; user[Account.TFA_BACKUPS] = ""; user[Account.TFA_INTERNAL] = ""; user[Account.ACCOUNT_TYPE] = Account.AT_INCOMPLETE; user[Account.ROLES] = new BsonArray(new BsonValue[] { }); return(user); }
public bool IsValidSessType(string inp) { // TODO: Match against database list return(ForumUtilities.ValidateUsername(inp) && inp.ToLowerInvariant() == inp); }