From b024a34cde4b281b66407b693a439514d9669bcb Mon Sep 17 00:00:00 2001
From: Adrian Schmitz <adrian.schmitz@rwth-aachen.de>
Date: Wed, 23 Aug 2023 11:14:08 +0200
Subject: [PATCH] Resolve "Support new verification method via id_tokens"

---
 core/authentication/JWTManager.py | 15 ++++++++++++++-
 core/job.py                       | 12 +++++++++++-
 utility/.gitlab/.template.yml     | 16 ++++++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/core/authentication/JWTManager.py b/core/authentication/JWTManager.py
index 3f661a0..e791141 100644
--- a/core/authentication/JWTManager.py
+++ b/core/authentication/JWTManager.py
@@ -2,7 +2,7 @@ import jwt
 import time
 
 
-def get_UID_PID(JWT, url):
+def get_UID_PID_ID_TOKEN(JWT, url):
     jwks_client = jwt.PyJWKClient(url)
     signing_key = jwks_client.get_signing_key_from_jwt(JWT)
     # wait for token to be valid
@@ -10,5 +10,18 @@ def get_UID_PID(JWT, url):
     data = jwt.decode(JWT,
                       signing_key.key,
                       algorithms=["RS256"],
+                      audience="aixCIlenz",
                       options={"verify_exp": False})
     return data["user_id"], data["project_id"]
+
+def get_UID_PID_CI_JOB_JWT(JWT, url):
+    jwks_client = jwt.PyJWKClient(url)
+    signing_key = jwks_client.get_signing_key_from_jwt(JWT)
+    # wait for token to be valid
+    time.sleep(2)
+    data = jwt.decode(JWT,
+                      signing_key.key,
+                      algorithms=["RS256"],
+                      options={"verify_exp": False})
+    return data["user_id"], data["project_id"]
+
diff --git a/core/job.py b/core/job.py
index 1d6738f..9f784bf 100644
--- a/core/job.py
+++ b/core/job.py
@@ -90,8 +90,18 @@ class Job:
         self.rt_utility_path = rep(settings["Runtime Utility Path"])
         self.scripts_path = f'{self.rt_utility_path}/scripts'
         if self.down_scoping:
-            uid, pid = jwt.get_UID_PID(get_cenv('CI_JOB_JWT'),
+            try:
+                uid, pid = jwt.get_UID_PID_ID_TOKEN(get_cenv('HPC_CI_TOKEN'),
+                                      f"{get_cenv('CI_SERVER_URL')}/-/jwks")
+            except:
+                logging.warn("id token HPC_CI_TOKEN, with aud: aixCIlence not defined.")
+                try:
+                    uid, pid = jwt.get_UID_PID_CI_JOB_JWT(get_cenv('CI_JOB_JWT'),
                                        f"{get_cenv('CI_SERVER_URL')}/-/jwks")
+                except:
+                    logging.error("No valid jwt available for verification")
+                    exit(1)
+
             self.account = man.get_account(get_cenv('CI_SERVER_URL'), pid, uid, self.key_path, self.map_path,
                                            self.aes_path)
             self.user_path = settings["User Path"].replace("$USER", self.account)
diff --git a/utility/.gitlab/.template.yml b/utility/.gitlab/.template.yml
index f62fdcd..78a6160 100644
--- a/utility/.gitlab/.template.yml
+++ b/utility/.gitlab/.template.yml
@@ -32,6 +32,10 @@ stages:          # List of stages for jobs, and their order of execution
 
 default:
   tags: [$RUNNER_TAG]
+  #  id_tokens:
+  # HPC_CI_TOKEN:
+  #   aud: aixCIlenz
+
 
 variables:
   SLURM_PARAM_TIMELIMIT: "-t 10:00"
@@ -214,6 +218,18 @@ fail-timeout-job:       # This job runs in the build stage, which runs first.
     - sleep 1200
   allow_failure: true
 
+idtoken-job:       # This job runs in the build stage, which runs first.
+  stage: build
+  id_tokens:
+    HPC_CI_TOKEN:
+      aud: aixCIlenz
+  variables:
+    SLURM_PARAM_CPUS: "-c 2"
+  script:
+    - module list
+    - echo "Compiling the code..."
+    - echo "Compile complete."
+
 build-job:       # This job runs in the build stage, which runs first.
   stage: build
   variables:
-- 
GitLab