Repository: PrefectHQ/prefect

Issue:
Having PREFECT_API_KEY as env var prevent from login to cloud
### First check

- [X] I added a descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the Prefect documentation for this issue.
- [X] I checked that this issue is related to Prefect and not one of its dependencies.

### Bug summary

When having `PREFECT_API_KEY` set as an environment variable, the `prefect cloud login` command will exit with `This profile is already authenticated with that key.` without being actually logged in.

### Reproduction

```python3
PREFECT_API_KEY=foo prefect cloud login -k foo
```


### Error

```python3
We are not actually logged in.
```


### Versions

```Text
Version:             2.7.0
API version:         0.8.3
Python version:      3.10.5
Git commit:          c2833339
Built:               Thu, Dec 1, 2022 4:03 PM
OS/Arch:             linux/x86_64
Profile:             default
Server type:         ephemeral
Server:
  Database:          sqlite
  SQLite version:    3.38.5
```


### Additional context

_No response_


Discussion:
Thanks for the bug report @Andarius! 
We've already got a utility to check if the key actually works so this should be a quick fix.
Hello @madkinsz and @bunchesofdonald,
I would like to look into this issue if it's not being worked on!
Great! Let us know if you have any questions :)
RUN prefect profile use default
RUN prefect cloud login -k abc --workspace cdf
just adding this here in case anyone else encounters: 
I thought just giving the key a different name could be a temporary fix, but it turns out this environment variable (with this exact name) has to be set, if not I'm getting errors like: `RuntimeError: Cannot create flow run. Failed to reach API` and so no flows can run


Resolving patch:
diff --git a/src/prefect/cli/cloud/__init__.py b/src/prefect/cli/cloud/__init__.py
--- a/src/prefect/cli/cloud/__init__.py
+++ b/src/prefect/cli/cloud/__init__.py
@@ -318,9 +318,24 @@ async def login(
 
     profiles = load_profiles()
     current_profile = get_settings_context().profile
+    env_var_api_key = PREFECT_API_KEY.value()
 
-    if key and PREFECT_API_KEY.value() == key:
-        exit_with_success("This profile is already authenticated with that key.")
+    if env_var_api_key and key and env_var_api_key != key:
+        exit_with_error(
+            "Cannot log in with a key when a different PREFECT_API_KEY is present as an"
+            " environment variable that will override it."
+        )
+
+    if env_var_api_key and env_var_api_key == key:
+        is_valid_key = await check_key_is_valid_for_login(key)
+        is_correct_key_format = key.startswith("pnu_") or key.startswith("pnb_")
+        if not is_valid_key:
+            help_message = "Please ensure your credentials are correct and unexpired."
+            if not is_correct_key_format:
+                help_message = "Your key is not in our expected format."
+            exit_with_error(
+                f"Unable to authenticate with Prefect Cloud. {help_message}"
+            )
 
     already_logged_in_profiles = []
     for name, profile in profiles.items():
@@ -395,10 +410,14 @@ async def login(
                     " (https://cloud.prefect.io). Make sure that you generate API key"
                     " using Cloud 2 (https://app.prefect.cloud)"
                 )
-            elif not key.startswith("pnu"):
-                help_message = "Your key is not in our expected format."
+            elif not key.startswith("pnu_") and not key.startswith("pnb_"):
+                help_message = (
+                    "Your key is not in our expected format: 'pnu_' or 'pnb_'."
+                )
             else:
-                help_message = "Please ensure your credentials are correct."
+                help_message = (
+                    "Please ensure your credentials are correct and unexpired."
+                )
             exit_with_error(
                 f"Unable to authenticate with Prefect Cloud. {help_message}"
             )


Test patch:
diff --git a/tests/cli/test_cloud.py b/tests/cli/test_cloud.py
--- a/tests/cli/test_cloud.py
+++ b/tests/cli/test_cloud.py
@@ -99,14 +99,14 @@ def mock_webbrowser(monkeypatch):
             "pnu_foo",
             (
                 "Unable to authenticate with Prefect Cloud. Please ensure your"
-                " credentials are correct."
+                " credentials are correct and unexpired."
             ),
         ),
         (
             "foo",
             (
                 "Unable to authenticate with Prefect Cloud. Your key is not in our"
-                " expected format."
+                " expected format: 'pnu_' or 'pnb_'."
             ),
         ),
     ],
@@ -122,6 +122,80 @@ def test_login_with_invalid_key(key, expected_output, respx_mock):
     )
 
 
+@pytest.mark.parametrize(
+    "key",
+    [
+        "pnu_foo",
+        "foo",
+    ],
+)
+def test_login_with_prefect_api_key_env_var_different_than_key_exits_with_error(key):
+    with temporary_settings({PREFECT_API_KEY: "pnu_baz"}):
+        invoke_and_assert(
+            ["cloud", "login", "--key", key, "--workspace", "foo"],
+            expected_code=1,
+            expected_output=(
+                "Cannot log in with a key when a different PREFECT_API_KEY is present"
+                " as an environment variable that will override it."
+            ),
+        )
+
+
+@pytest.mark.parametrize(
+    "env_var_api_key,key,expected_output",
+    [
+        (
+            "pnu_foo",
+            "pnu_foo",
+            (
+                "Unable to authenticate with Prefect Cloud. Please ensure your"
+                " credentials are correct and unexpired."
+            ),
+        ),
+        (
+            "foo",
+            "foo",
+            (
+                "Unable to authenticate with Prefect Cloud. Your key is not in our"
+                " expected format."
+            ),
+        ),
+    ],
+)
+def test_login_with_prefect_api_key_env_var_equal_to_invalid_key_exits_with_error(
+    key, expected_output, env_var_api_key, respx_mock
+):
+    respx_mock.get(PREFECT_CLOUD_API_URL.value() + "/me/workspaces").mock(
+        return_value=httpx.Response(status.HTTP_403_FORBIDDEN)
+    )
+    with temporary_settings({PREFECT_API_KEY: env_var_api_key}):
+        invoke_and_assert(
+            ["cloud", "login", "--key", key, "--workspace", "test/foo"],
+            expected_code=1,
+            expected_output=(expected_output),
+        )
+
+
+def test_login_with_prefect_api_key_env_var_equal_to_valid_key_succeeds(respx_mock):
+    foo_workspace = gen_test_workspace(account_handle="test", workspace_handle="foo")
+
+    respx_mock.get(PREFECT_CLOUD_API_URL.value() + "/me/workspaces").mock(
+        return_value=httpx.Response(
+            status.HTTP_200_OK,
+            json=[foo_workspace.dict(json_compatible=True)],
+        )
+    )
+
+    with temporary_settings({PREFECT_API_KEY: "pnu_foo"}):
+        invoke_and_assert(
+            ["cloud", "login", "--key", "pnu_foo", "--workspace", "test/foo"],
+            expected_code=0,
+            expected_output=(
+                "Authenticated with Prefect Cloud! Using workspace 'test/foo'."
+            ),
+        )
+
+
 def test_login_with_key_and_missing_workspace(respx_mock):
     foo_workspace = gen_test_workspace(account_handle="test", workspace_handle="foo")
     bar_workspace = gen_test_workspace(account_handle="test", workspace_handle="bar")