Repository: fsspec/gcsfs
Pull request #554 (2023-05-20 01:51:10)

GCSFileSystem can accept a raw token
Related to https://github.com/fsspec/gcsfs/issues/553.

`Credentials` will happily be created from an invalid token - google library doesn't seem to do any checks when the object is instantiated. However, when using such an instance of `Credentials`, an `HttpError` will be raised.


martindurant: > things will break down the line.

Something other than permission errors?

Patch:
diff --git a/gcsfs/credentials.py b/gcsfs/credentials.py
index 05439b9..a6e8d37 100644
--- a/gcsfs/credentials.py
+++ b/gcsfs/credentials.py
@@ -139,22 +139,24 @@ class GoogleCredentials:
         Parameters
         ----------
         token: str, dict or Credentials
-            If a str, try to load as a Service file, or next as a JSON; if
+            If a str and a valid file name, try to load as a Service file, or next as a JSON;
+            if not a valid file name, assume it's a valid raw (non-renewable/session) token, and pass to Credentials. If
             dict, try to interpret as credentials; if Credentials, use directly.
         """
         if isinstance(token, str):
-            if not os.path.exists(token):
-                raise FileNotFoundError(token)
-            try:
-                # is this a "service" token?
-                self._connect_service(token)
-                return
-            except:  # noqa: E722
-                # TODO: catch specific exceptions
-                # some other kind of token file
-                # will raise exception if is not json
-                with open(token) as data:
-                    token = json.load(data)
+            if os.path.exists(token):
+                try:
+                    # is this a "service" token?
+                    self._connect_service(token)
+                    return
+                except:  # noqa: E722
+                    # TODO: catch specific exceptions
+                    # some other kind of token file
+                    # will raise exception if is not json
+                    with open(token) as data:
+                        token = json.load(data)
+            else:
+                token = Credentials(token)
         if isinstance(token, dict):
             credentials = self._dict_to_credentials(token)
         elif isinstance(token, google.auth.credentials.Credentials):


Test patch:
diff --git a/gcsfs/tests/test_credentials.py b/gcsfs/tests/test_credentials.py
index c311988..5c1bb65 100644
--- a/gcsfs/tests/test_credentials.py
+++ b/gcsfs/tests/test_credentials.py
@@ -1,7 +1,18 @@
+import pytest
+
+from gcsfs import GCSFileSystem
 from gcsfs.credentials import GoogleCredentials
+from gcsfs.retry import HttpError
 
 
 def test_googlecredentials_none():
     credentials = GoogleCredentials(project="myproject", token=None, access="read_only")
     headers = {}
     credentials.apply(headers)
+
+
+@pytest.mark.parametrize("token", ["", "incorrect.token", "x" * 100])
+def test_credentials_from_raw_token(token):
+    with pytest.raises(HttpError, match="Invalid Credentials"):
+        fs = GCSFileSystem(project="myproject", token=token)
+        fs.ls("/")