username = params_kw.get('username') passwd = params_kw.get('passwd') if not passwd: return UiError(title='Login failed', message='Password is required') passwd = password_encode(passwd) rzt = await check_user_password(request, username, passwd) if rzt: return UiMessage(title='Logined', message='Welcome back') # Check if account is locked for better error message db = DBPools() dbname = get_module_dbname('rbac') async with db.sqlorContext(dbname) as sor: r = await sor.sqlExe('select login_fail_count, last_login_fail from users where username=${username}$', {'username': username}) if r: fail_count = getattr(r[0], 'login_fail_count', 0) or 0 if fail_count >= 3: return UiError(title='Account Locked', message='Account locked due to too many failed login attempts. Please try again in 5 minutes.') remaining = 3 - fail_count return UiError(title='Login failed', message=f'User and password mismatch ({remaining} attempts remaining)') return UiError(title='Login failed', message='User and password mismatch')