//Low-level methods
        public ILogin FindLogin(IEntitySession session, string userName, string password, Guid?tenantId)
        {
            var context = session.Context;

            context.ValidateNotEmpty(userName, ClientFaultCodes.ValueMissing, "UserName", null, "UserName may not be empty");
            context.ValidateNotEmpty(password, ClientFaultCodes.ValueMissing, "Password", null, "Password may not be empty");
            context.ThrowValidation();
            userName = CheckUserName(context, userName);
            var userNameHash  = Util.StableHash(userName);
            var weakPwdHash   = GetWeakPasswordHash(password);
            var tenantIdValue = tenantId == null ? Guid.Empty : tenantId.Value;
            // Note: we do not compare usernames, only UserNameHash values; UserName might be null if we don't save them
            var qryLogins = from lg in session.EntitySet <ILogin>()
                            where lg.UserNameHash == userNameHash && lg.WeakPasswordHash == weakPwdHash &&
                            lg.TenantId == tenantIdValue
                            select lg;

            //Query logins table
            using (session.WithElevateRead()) {
                var logins = qryLogins.ToList(); //these are candidates, but most often will be just one
                var login  = logins.FirstOrDefault(lg => VerifyPassword(lg, password));
                if (login != null)
                {
                    VerifyExpirationSuspensionDates(login);
                }
                return(login);
            }
        }
 public IOAuthClientFlow BeginOAuthFlow(IEntitySession session, Guid userId, string serverName, string scopes = null)
 {
     using (session.WithElevateRead()) {
         var acct = session.GetOAuthAccount(serverName);
         session.Context.ThrowIfNull(acct, ClientFaultCodes.ObjectNotFound, "serverName", "Account not registered for server {0}.", serverName);
         scopes = string.IsNullOrWhiteSpace(scopes) ? acct.Server.Scopes : scopes; //take all scopes
         var flow = acct.BeginOAuthFlow(userId, scopes);
         return(flow);
     }
 }
 //Low-level methods
 public ILogin FindLogin(IEntitySession session, string userName, string password, Guid? tenantId)
 {
     var context = session.Context;
       context.ValidateNotEmpty(userName, ClientFaultCodes.ValueMissing, "UserName", null, "UserName may not be empty");
       context.ValidateNotEmpty(password, ClientFaultCodes.ValueMissing, "Password", null, "Password may not be empty");
       context.ThrowValidation();
       userName = CheckUserName(context, userName);
       var userNameHash = Util.StableHash(userName);
       var weakPwdHash = GetWeakPasswordHash(password);
       var tenantIdValue = tenantId == null ? Guid.Empty : tenantId.Value;
       // Note: we do not compare usernames, only UserNameHash values; UserName might be null if we don't save them
       var qryLogins = from lg in session.EntitySet<ILogin>()
               where lg.UserNameHash == userNameHash && lg.WeakPasswordHash == weakPwdHash
                 && lg.TenantId == tenantIdValue
               select lg;
       //Query logins table
       using(session.WithElevateRead()) {
     var logins = qryLogins.ToList(); //these are candidates, but most often will be just one
     var login = logins.FirstOrDefault(lg => VerifyPassword(lg, password));
     if(login != null)
       VerifyExpirationSuspensionDates(login);
     return login;
       }
 }