private async Task <UserEntry> AuthenticateByOneDB(string email, string tenantID, ClusterContext db, UserID userID) { var priorEntrys = db.User.Where(b => b.Email == email).ToAsyncEnumerable(); long nEntry = 0; UserEntry ret = null; // Prior entry exists? await priorEntrys.ForEachAsync(entry => { // We will not update existing entry in database. // db.Entry(entry).CurrentValues.SetValues(userEntry); ret = entry; Interlocked.Add(ref nEntry, 1); } ); if (Interlocked.Read(ref nEntry) == 0) { if (!Object.ReferenceEquals(userID, null)) { string password = Guid.NewGuid().ToString().Substring(0, 8); UserEntry userEntry = new UserEntry(userID, email, email, password); await db.User.AddAsync(userEntry); await db.SaveChangesAsync(); return(userEntry); } else { return(null); } } else { // Prior entry exists, we use the database as the authorative source. UserEntry newEntry = ret; // Update is AuthorizedEntry only, other entry will be updated by database. if (!Object.ReferenceEquals(userID, null)) { bool bUpdate = false; if (String.Compare(ret.isAuthorized, userID.isAuthorized, true) < 0 || String.Compare(ret.isAdmin, userID.isAdmin, true) < 0) { // userID isAuthorized is true newEntry.isAuthorized = userID.isAuthorized; newEntry.isAdmin = userID.isAdmin; newEntry.uid = userID.uid; newEntry.gid = userID.gid; bUpdate = true; } if (bUpdate) { db.Entry(ret).CurrentValues.SetValues(newEntry); await db.SaveChangesAsync(); } } if (newEntry.Alias != newEntry.Email) { return(await AuthenticateByOneDB(newEntry.Alias, tenantID, db, userID)); } else { return(newEntry); } } }