protected function handleLogin(Request $httpRequest)
    {
        $post = $httpRequest->request;
        if (!$post->has("username") || !$post->has("password")) {
            return;
        }

        //CSRF validation
        if (!$this->picoAuth->isValidCSRF($post->get("csrf_token"), self::LOGIN_CSRF_ACTION)) {
            $this->picoAuth->redirectToLogin(null, $httpRequest);
            return;
        }

        $username = strtolower(trim($post->get("username")));
        $password = new Password($post->get("password"));

        //Check if the login action is not rate limited
        if (!$this->limit->action("login", false, array("name" => $username))) {
            $this->session->addFlash("error", $this->limit->getError());
            $this->picoAuth->redirectToLogin(null, $httpRequest);
            return;
        }

        if (!$this->loginAttempt($username, $password)) {
            $this->logInvalidLoginAttempt($username);
            $this->limit->action("login", true, array("name" => $username));
            $this->session->addFlash("error", "Invalid username or password");
            $this->picoAuth->redirectToLogin(null, $httpRequest);
            return;
        } else {
            $userData = $this->storage->getUserByName($username);
            if ($this->needsPasswordRehash($userData)) {
                $this->passwordRehash($username, $password);
            }
            $this->login($username, $userData);
            $this->picoAuth->afterLogin();
        }
    }