Repository: obspy/obspy

Issue:
FDSN EIDA token auth: allow signed messages as token files
The following line of `_validate_eida_token `:

https://github.com/obspy/obspy/blob/454f4abe734c85bfc528af2cb43499bf7343cc72/obspy/clients/fdsn/client.py#L1909

Issues in my case a "false positive" as I am working with an EIDA token with the "header":

BEGIN PGP SIGNED MESSAGE

instead of

BEGIN PGP MESSAGE.

One possible fix  is to simply change the regex pattern to something less strict, e.g.:
```
if re.search(pattern=r'\bBEGIN PGP\b', string=token, 
```

I can issue a PR but beforehand I would like to get some insights: as I am not a token expert, maybe `_validate_eida_token ` prevents some subtle issues I am unaware of.

Thank you very much 




Discussion:
Any feedback?
Feel free to send a PR against `master` @rizac. Does the token mechanism work in any case? I'm quite confused with the EIDA setup and I don't think we have a real test case on any server that we can use to request restricted data.

In any case you should be able to work around this problem by simply removing the signature block in your token file and getting rid of ` SIGNED` keywords as well?
Oh and you can convert your issue into a PR to avoid duplicated tickets, see https://github.com/obspy/obspy/wiki/Interesting-Reading-on-Git%2C-GitHub

Resolving patch:
diff --git a/obspy/clients/fdsn/client.py b/obspy/clients/fdsn/client.py
--- a/obspy/clients/fdsn/client.py
+++ b/obspy/clients/fdsn/client.py
@@ -291,7 +291,7 @@ def set_credentials(self, user, password):
         self.user = user
         self._set_opener(user, password)
 
-    def set_eida_token(self, token):
+    def set_eida_token(self, token, validate=True):
         """
         Fetch user and password from the server using the provided token,
         resulting in subsequent web service requests for waveforms being
@@ -308,8 +308,11 @@ def set_eida_token(self, token):
             This mechanism is only available on select EIDA nodes. The token
             can be provided in form of the PGP message as a string, or the
             filename of a local file with the PGP message in it.
+        :type validate: bool
+        :param validate: Whether to sanity check the token before sending it to
+            the EIDA server or not.
         """
-        user, password = self._resolve_eida_token(token)
+        user, password = self._resolve_eida_token(token, validate=validate)
         self.set_credentials(user, password)
 
     def _set_opener(self, user, password):
@@ -333,7 +336,7 @@ def _set_opener(self, user, password):
         if self.debug:
             print('Installed new opener with handlers: {!s}'.format(handlers))
 
-    def _resolve_eida_token(self, token):
+    def _resolve_eida_token(self, token, validate=True):
         """
         Use the token to get credentials.
         """
@@ -350,16 +353,17 @@ def _resolve_eida_token(self, token):
             with open(token_file, 'rb') as fh:
                 token = fh.read().decode()
         # sanity check on the token
-        if not _validate_eida_token(token):
-            if token_file:
-                msg = ("Read EIDA token from file '{}' but it does not "
-                       "seem to contain a valid PGP message.").format(
-                            token_file)
-            else:
-                msg = ("EIDA token does not seem to be a valid PGP message. "
-                       "If you passed a filename, make sure the file "
-                       "actually exists.")
-            raise ValueError(msg)
+        if validate:
+            if not _validate_eida_token(token):
+                if token_file:
+                    msg = ("Read EIDA token from file '{}' but it does not "
+                           "seem to contain a valid PGP message.").format(
+                                token_file)
+                else:
+                    msg = ("EIDA token does not seem to be a valid PGP "
+                           "message. If you passed a filename, make sure the "
+                           "file actually exists.")
+                raise ValueError(msg)
 
         # force https so that we don't send around tokens unsecurely
         url = 'https://{}/fdsnws/dataselect/1/auth'.format(
@@ -1910,6 +1914,9 @@ def _validate_eida_token(token):
     if re.search(pattern='BEGIN PGP MESSAGE', string=token,
                  flags=re.IGNORECASE):
         return True
+    elif re.search(pattern='BEGIN PGP SIGNED MESSAGE', string=token,
+                   flags=re.IGNORECASE):
+        return True
     return False
 
 


Test patch: