diff options
author | Francois Kritzinger <francois@codesynthesis.com> | 2024-02-06 16:35:59 +0200 |
---|---|---|
committer | Francois Kritzinger <francois@codesynthesis.com> | 2024-04-24 15:14:54 +0200 |
commit | b94085e6de4317bda2a0dc656f93902cf7f95fd4 (patch) | |
tree | 961f7dc7b8a7e86c78887b2582e1a7a6a532937f /mod/mod-ci-github.cxx | |
parent | 74ea483c1444f9e0f2faa5d7e3418e7d915bc279 (diff) |
Generate JWT
Diffstat (limited to 'mod/mod-ci-github.cxx')
-rw-r--r-- | mod/mod-ci-github.cxx | 78 |
1 files changed, 28 insertions, 50 deletions
diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index 0a28b63..a82ce43 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -5,8 +5,10 @@ #include <libbutl/json/parser.hxx> +#include <mod/jwt.hxx> #include <mod/module-options.hxx> +#include <stdexcept> #include <iostream> // @@ TODO @@ -62,55 +64,6 @@ // // - Generate a JSON Web Token (JWT) // -// The inputs are (one of) the application's private key(s) and the -// application ID, which goes into the "issuer" JWT field. Also the -// token's issued time and expiration time (10 minutes max). -// -// The best library for us seems to be libjwt at -// https://github.com/benmcollins/libjwt which is also widely packaged -// (most Linux distros and Homebrew). -// -// Doing it ourselves: -// -// Github requires the RS256 algorithm, which is RSA signing using -// SHA256. -// -// The message consists of a base64url-encoded JSON header and -// payload. (base64url differs from base64 by having different 62nd and -// 63rd alphabet characters (- and _ instead of ~ and . to make it -// filesystem-safe) and no padding because the padding character '=' is -// unsafe in URIs.) -// -// Header: -// -// { -// "alg": "RS256", -// "typ": "JWT" -// } -// -// Payload: -// -// { -// "iat": 1234567, -// "exp": 1234577, -// "iss": "<APP_ID>" -// } -// -// Where: -// iat := Issued At (NumericDate) -// exp := Expires At (NumericDate) -// iss := Issuer -// -// Signature: -// -// RSA_SHA256(PKEY, base64url($header) + "." + base64url($payload)) -// -// JWT: -// -// base64url($header) + "." + -// base64url($payload) + "." + -// base64url($signature) -// // - Get the installation ID. This will be included in the webhook request // in our case // @@ -135,7 +88,7 @@ brep::ci_github::ci_github (const ci_github& r) void brep::ci_github:: init (scanner& s) { - options_ = make_shared<options::ci> ( + options_ = make_shared<options::ci_github> ( s, unknown_mode::fail, unknown_mode::fail); } @@ -278,6 +231,31 @@ handle (request& rq, response& rs) cout << "<check_suite webhook>" << endl << cs << endl; + try + { + // Use the maximum validity period allowed by GitHub (10 minutes). + // + string jwt (gen_jwt (*options_, + options_->ci_github_app_private_key (), + to_string (options_->ci_github_app_id ()), + chrono::minutes (10))); + + if (jwt.empty ()) + fail << "unable to generate JWT: " << options_->openssl () + << " failed"; + + cout << "JWT: " << jwt << endl; + } + catch (const system_error& e) + { + fail << "unable to generate JWT: unable to execute " + << options_->openssl () << ": " << e.what (); + } + catch (const std::exception& e) + { + fail << "unable to generate JWT: " << e; + } + return true; } else if (event == "pull_request") |