From 24c52c8d69bfbfd593b1f740d133ffd5e086d97c Mon Sep 17 00:00:00 2001 From: Tomas Hozza Date: Thu, 4 Aug 2022 12:36:57 +0200 Subject: [PATCH] osbuild-mock-openid-provider: support `client_credentials` grant type Extend the implementation of mock openid server to take the `grant_type` into consideration for the `/token` endpoint. In addition to the previously supported `refresh_topen`, the implementation now supports also `client_credentials`. This is necessary to make it possible to use the mock server in the `koji-osbuild` CI, because the builder plugin uses `client_credentials` to get access token. The implementation behaves in the following way: - For `refresh_token` grant type, it takes the `refresh_token` value from the request and adds it to the `rh-org-id` field in the custom claim, which is part of the returned token. - For `client_credentials` grant type, it takes the `client_secret` value from the request and adds it to the `rh-org-id` field in the custom claim, which is part of the returned token. Requests without the supported `grant_type` set are rejected. Modify affected test cases to specify `grant_type` when fetching a new access token. --- cmd/osbuild-mock-openid-provider/main.go | 28 +++++++++++++++++++----- test/cases/api.sh | 3 ++- test/cases/api/common/common.sh | 1 + tools/koji-compose.py | 5 ++++- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/cmd/osbuild-mock-openid-provider/main.go b/cmd/osbuild-mock-openid-provider/main.go index 7b04e2664..7f5bea27b 100644 --- a/cmd/osbuild-mock-openid-provider/main.go +++ b/cmd/osbuild-mock-openid-provider/main.go @@ -90,13 +90,29 @@ func main() { panic(err) } - cc := customClaims{ - Type: "Bearer", - ExpiresAt: 0, - IssuedAt: time.Now().Unix(), - // Use refresh_token as rh-org-id - RHOrgID: r.Form.Get("refresh_token"), + var cc customClaims + switch r.Form.Get("grant_type") { + case "refresh_token": + cc = customClaims{ + Type: "Bearer", + ExpiresAt: 0, + IssuedAt: time.Now().Unix(), + // Use refresh_token as rh-org-id + RHOrgID: r.Form.Get("refresh_token"), + } + case "client_credentials": + cc = customClaims{ + Type: "Bearer", + ExpiresAt: 0, + IssuedAt: time.Now().Unix(), + // Use client_secret as rh-org-id + RHOrgID: r.Form.Get("client_secret"), + } + default: + w.WriteHeader(http.StatusBadRequest) + return } + token := jwt.NewWithClaims(jwt.SigningMethodRS256, cc) token.Header["kid"] = "key-id" diff --git a/test/cases/api.sh b/test/cases/api.sh index 58414239f..d77a1d70e 100755 --- a/test/cases/api.sh +++ b/test/cases/api.sh @@ -528,11 +528,12 @@ KILL_PIDS+=("$!") sudo systemctl restart osbuild-composer -until curl --output /dev/null --silent --fail localhost:8081/token; do +until curl --data "grant_type=refresh_token" --output /dev/null --silent --fail localhost:8081/token; do sleep 0.5 done TOKEN="$(curl --request POST \ + --data "grant_type=refresh_token" \ --data "refresh_token=$REFRESH_TOKEN" \ --header "Content-Type: application/x-www-form-urlencoded" \ --silent \ diff --git a/test/cases/api/common/common.sh b/test/cases/api/common/common.sh index ba5f1c44a..0051b83e5 100644 --- a/test/cases/api/common/common.sh +++ b/test/cases/api/common/common.sh @@ -60,6 +60,7 @@ function access_token { function access_token_with_org_id { local refresh_token="$1" curl --request POST \ + --data "grant_type=refresh_token" \ --data "refresh_token=$refresh_token" \ --header "Content-Type: application/x-www-form-urlencoded" \ --silent \ diff --git a/tools/koji-compose.py b/tools/koji-compose.py index c61f0c27d..065f34db0 100755 --- a/tools/koji-compose.py +++ b/tools/koji-compose.py @@ -127,7 +127,10 @@ class ComposerAPIClient: self.auth_server = auth_server def access_token(self): - resp = requests.post(self.auth_server + "/token", data={"refresh_token": self.refresh_token}) + resp = requests.post(self.auth_server + "/token", data={ + "grant_type": "refresh_token", + "refresh_token": self.refresh_token, + }) if resp.status_code != 200: raise RuntimeError(f"failed to refresh token: {resp.text}") return resp.json()["access_token"]