aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-ci-github.cxx
diff options
context:
space:
mode:
authorFrancois Kritzinger <francois@codesynthesis.com>2024-02-06 16:35:59 +0200
committerFrancois Kritzinger <francois@codesynthesis.com>2024-04-24 15:14:54 +0200
commitb94085e6de4317bda2a0dc656f93902cf7f95fd4 (patch)
tree961f7dc7b8a7e86c78887b2582e1a7a6a532937f /mod/mod-ci-github.cxx
parent74ea483c1444f9e0f2faa5d7e3418e7d915bc279 (diff)
Generate JWT
Diffstat (limited to 'mod/mod-ci-github.cxx')
-rw-r--r--mod/mod-ci-github.cxx78
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")