This is an automated email from the ASF dual-hosted git repository.

juergbi pushed a commit to branch juerg/token-auth
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit 12a9d4853c9644b419fc787a16c86623b33a67a9
Author: Jürg Billeter <[email protected]>
AuthorDate: Fri Jun 14 08:57:20 2024 +0200

    _remotespec.py: Add `access-token` config
    
    This adds support for optional HTTP bearer authentication via
    buildbox-casd.
    
    This requires buildbox-casd 1.2.8 or later.
---
 doc/source/using_config.rst                |  6 ++++++
 src/buildstream/_cas/casdprocessmanager.py |  2 ++
 src/buildstream/_remotespec.py             | 24 ++++++++++++++++++------
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/doc/source/using_config.rst b/doc/source/using_config.rst
index 926b56438..cf42119be 100644
--- a/doc/source/using_config.rst
+++ b/doc/source/using_config.rst
@@ -150,6 +150,7 @@ toplevel of your configuration file, like so:
          server-cert: server.crt
          client-cert: client.crt
          client-key: client.key
+         access-token: access.token
 
 
 Attributes
@@ -710,6 +711,7 @@ The ``auth`` configuration block looks like this:
      server-cert: server.crt
      client-cert: client.crt
      client-key: client.key
+     access-token: access.token
 
 
 Attributes
@@ -734,6 +736,10 @@ Attributes
   The client key is used to encrypt traffic when uploading traffic
   to the server.
 
+* ``access-token``
+
+  The path to a token for optional HTTP bearer authentication.
+
 Normally, only the ``server-cert`` is required to securely *download* data
 from remote cache services, while both the ``client-key`` and ``client-cert``
 is required to securely *upload* data to the server.
diff --git a/src/buildstream/_cas/casdprocessmanager.py 
b/src/buildstream/_cas/casdprocessmanager.py
index 452a98a60..f65ad4bcc 100644
--- a/src/buildstream/_cas/casdprocessmanager.py
+++ b/src/buildstream/_cas/casdprocessmanager.py
@@ -93,6 +93,8 @@ class CASDProcessManager:
             if remote_cache_spec.client_key_file:
                 
casd_args.append("--cas-client-key={}".format(remote_cache_spec.client_key_file))
                 
casd_args.append("--cas-client-cert={}".format(remote_cache_spec.client_cert_file))
+            if remote_cache_spec.access_token_file:
+                
casd_args.append("--cas-access-token={}".format(remote_cache_spec.access_token_file))
             if remote_cache_spec.keepalive_time is not None:
                 
casd_args.append("--cas-keepalive-time={}".format(remote_cache_spec.keepalive_time))
 
diff --git a/src/buildstream/_remotespec.py b/src/buildstream/_remotespec.py
index 0fa3cdd12..0845a35cd 100644
--- a/src/buildstream/_remotespec.py
+++ b/src/buildstream/_remotespec.py
@@ -71,6 +71,7 @@ class RemoteSpec:
         server_cert: str = None,
         client_key: str = None,
         client_cert: str = None,
+        access_token: str = None,
         instance_name: Optional[str] = None,
         connection_config: Optional[MappingNode] = None,
         spec_node: Optional[MappingNode] = None,
@@ -96,6 +97,7 @@ class RemoteSpec:
         self.server_cert_file: Optional[str] = server_cert
         self.client_key_file: Optional[str] = client_key
         self.client_cert_file: Optional[str] = client_cert
+        self.access_token_file: Optional[str] = access_token
 
         #
         # Private members
@@ -133,6 +135,7 @@ class RemoteSpec:
                 self.server_cert_file,
                 self.client_key_file,
                 self.client_cert_file,
+                self.access_token_file,
                 self.keepalive_time,
             )
         )
@@ -232,6 +235,8 @@ class RemoteSpec:
             remote.client_key = self.client_key
         if self.client_cert:
             remote.client_cert = self.client_cert
+        if self.access_token_file:
+            remote.access_token_path = self.access_token_file
         if self.keepalive_time is not None:
             remote.keepalive_time.FromSeconds(self.keepalive_time)
 
@@ -257,6 +262,7 @@ class RemoteSpec:
         server_cert: Optional[str] = None
         client_key: Optional[str] = None
         client_cert: Optional[str] = None
+        access_token: Optional[str] = None
         push: bool = False
         remote_type: str = RemoteType.ENDPOINT
 
@@ -281,7 +287,7 @@ class RemoteSpec:
 
         auth_node = spec_node.get_mapping("auth", None)
         if auth_node:
-            server_cert, client_key, client_cert = cls._parse_auth(auth_node, 
basedir)
+            server_cert, client_key, client_cert, access_token = 
cls._parse_auth(auth_node, basedir)
 
         connection_config = spec_node.get_mapping("connection-config", None)
 
@@ -292,6 +298,7 @@ class RemoteSpec:
             server_cert=server_cert,
             client_key=client_key,
             client_cert=client_cert,
+            access_token=access_token,
             instance_name=instance_name,
             connection_config=connection_config,
             spec_node=spec_node,
@@ -323,6 +330,7 @@ class RemoteSpec:
         server_cert: Optional[str] = None
         client_key: Optional[str] = None
         client_cert: Optional[str] = None
+        access_token: Optional[str] = None
 
         if purpose == RemoteSpecPurpose.PULL:
             push = False
@@ -371,6 +379,8 @@ class RemoteSpec:
                     client_key = cls._resolve_path(val, os.getcwd())
                 elif key == "client-cert":
                     client_cert = cls._resolve_path(val, os.getcwd())
+                elif key == "access-token":
+                    access_token = cls._resolve_path(val, os.getcwd())
                 else:
                     raise RemoteError("Unexpected key '{}' 
encountered".format(key))
         else:
@@ -387,6 +397,7 @@ class RemoteSpec:
             server_cert=server_cert,
             client_key=client_key,
             client_cert=client_cert,
+            access_token=access_token,
             instance_name=instance_name,
         )
 
@@ -417,15 +428,15 @@ class RemoteSpec:
     #    basedir: The base directory which cert files are relative to, or None
     #
     # Returns:
-    #    A 3 tuple containing the filenames for the server-cert,
-    #    the client-key and the client-cert
+    #    A 4 tuple containing the filenames for the server-cert,
+    #    the client-key, the client-cert and the access-token
     #
     @classmethod
     def _parse_auth(
         cls, auth_node: MappingNode, basedir: Optional[str] = None
-    ) -> Tuple[Optional[str], Optional[str], Optional[str]]:
+    ) -> Tuple[Optional[str], Optional[str], Optional[str], Optional[str]]:
 
-        auth_keys = ["server-cert", "client-key", "client-cert"]
+        auth_keys = ["server-cert", "client-key", "client-cert", 
"access-token"]
         auth_values = {}
         auth_node.validate_keys(auth_keys)
 
@@ -438,6 +449,7 @@ class RemoteSpec:
         server_cert = auth_values["server-cert"]
         client_key = auth_values["client-key"]
         client_cert = auth_values["client-cert"]
+        access_token = auth_values["access-token"]
 
         if client_key and not client_cert:
             provenance = auth_node.get_node("client-key").get_provenance()
@@ -451,7 +463,7 @@ class RemoteSpec:
                 "{}: 'client-cert' was specified without 
'client-key'".format(provenance), LoadErrorReason.INVALID_DATA
             )
 
-        return server_cert, client_key, client_cert
+        return server_cert, client_key, client_cert, access_token
 
     # _load_credential_files():
     #

Reply via email to