From 978708a3828b8468d0d911186a3b14fecb7da295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Thu, 8 Sep 2022 14:24:07 +0200 Subject: [PATCH] Make the app id and private key optional in tests Fixes #280 --- ...eplayEventRouteAvailableInDevModeTest.java | 2 +- .../signing/PayloadSignatureCheckerTest.java | 3 +- .../resources/application-for-dev.properties | 31 ++++++++ .../src/test/resources/application.properties | 31 +------- .../ROOT/pages/includes/attributes.adoc | 7 -- .../pages/includes/quarkus-github-app.adoc | 10 +-- docs/modules/ROOT/pages/testing.adoc | 36 ---------- .../src/main/resources/application.properties | 31 +------- .../config/GitHubAppRuntimeConfig.java | 8 ++- .../runtime/github/GitHubService.java | 72 +++++++++++++++++-- 10 files changed, 116 insertions(+), 115 deletions(-) create mode 100644 deployment/src/test/resources/application-for-dev.properties delete mode 100644 docs/modules/ROOT/pages/includes/attributes.adoc diff --git a/deployment/src/test/java/io/quarkiverse/githubapp/deployment/replay/ReplayEventRouteAvailableInDevModeTest.java b/deployment/src/test/java/io/quarkiverse/githubapp/deployment/replay/ReplayEventRouteAvailableInDevModeTest.java index 42b9d3cd..2def6797 100644 --- a/deployment/src/test/java/io/quarkiverse/githubapp/deployment/replay/ReplayEventRouteAvailableInDevModeTest.java +++ b/deployment/src/test/java/io/quarkiverse/githubapp/deployment/replay/ReplayEventRouteAvailableInDevModeTest.java @@ -13,7 +13,7 @@ public class ReplayEventRouteAvailableInDevModeTest { @RegisterExtension public static final QuarkusDevModeTest test = new QuarkusDevModeTest() .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) - .addAsResource("application.properties")); + .addAsResource("application-for-dev.properties", "application.properties")); @Test public void testPayloadSignatureCheck() { diff --git a/deployment/src/test/java/io/quarkiverse/githubapp/deployment/signing/PayloadSignatureCheckerTest.java b/deployment/src/test/java/io/quarkiverse/githubapp/deployment/signing/PayloadSignatureCheckerTest.java index 08b4885d..67480bb8 100644 --- a/deployment/src/test/java/io/quarkiverse/githubapp/deployment/signing/PayloadSignatureCheckerTest.java +++ b/deployment/src/test/java/io/quarkiverse/githubapp/deployment/signing/PayloadSignatureCheckerTest.java @@ -22,7 +22,8 @@ public class PayloadSignatureCheckerTest { .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) .addClass(PayloadUtil.class) .addAsResource(PAYLOAD)) - .withConfigurationResource("application.properties"); + .withConfigurationResource("application.properties") + .overrideConfigKey("quarkus.github-app.webhook-secret", "cs5WKyOlY6go0E1RbkAOf0jq5K4KWBcP"); @Inject PayloadSignatureChecker payloadSignatureChecker; diff --git a/deployment/src/test/resources/application-for-dev.properties b/deployment/src/test/resources/application-for-dev.properties new file mode 100644 index 00000000..3772ae13 --- /dev/null +++ b/deployment/src/test/resources/application-for-dev.properties @@ -0,0 +1,31 @@ +# Don't name this file application-dev.properties or it will get picked up +# for every single test, including those that don't reference this file... +quarkus.github-app.app-id=1234 +quarkus.github-app.app-name=quarkus-github-app-test +quarkus.github-app.private-key=-----BEGIN RSA PRIVATE KEY-----\ +MIIEowIBAAKCAQEAtsCKYkMzgqSsbkcPThTjeYnd6r5RAS4q5SyiOyIf34nYH5D0\ +jy8Dlt1s8u69KmBoM9Neesqf2Yh80b/UNUtea9knpgR4ME+MIg1LdsLnUWoZuPBl\ +lLaMfwRkN4+ZbTJ7Uo98UUlxoTcCjZVzopSoIazuUF5u+01sx6QEcHB312s42FVL\ +gkd8T36wvIywseOPKr2oyCMQ2AdcxL/cEHwx2hcQAe+eTipsxNy4atIhbDWrML5W\ +v7cYlyn9/sKgxkXtW3eInP3VI3FS+IH+cjwO4FS6ez8TT6USfaCjDb4LgdEKt/de\ +Ds4TbqwM2vjqedLNBhE7t4V2Uf3STdFq+cKHwwIDAQABAoIBAE07MUA1hh8/2F8C\ +SMWGrls+mDoME8+b4yTWp/i1gyLE7kDo0XFxPOMU0GYZ3nd6Jo9AVD0wRD16IMXD\ +e7rKDy0kqEzQtroz49TAKZQW6grN+/DcJxGh094ZzQBt/zjWjKdnW/I+R3cJ+Fo9\ +PpEGoccZfd0ZC23IWqBEAFxEK2Eth7CbJW5eMJElyqSZa9jiF6wdnryH4Xww38iE\ +zv5tL2Ieg03lxj0mdeyzFyIzJTk3PEAFLIjIiducIhSWyJHltpKQEZ3iFMzKfx7l\ +qLIczsyLRouc64+T7lW1PO6SQshHlvc6CtJaHHf98iFMDwdDlSolF/PfNLE5C6lA\ +U0KGUYECgYEA5xcnO9nv58QdcMXobHWethh+a2QTWmEXbE/Lnunqgq+bTgJUbgXR\ +Fi+awb+6GI8lJh16oBbzSRGe2pFQcQa9S84+CnAyVVyras4WC5bcl38q46wh0IRW\ +2sqvJfAI/CJZxgLVceELJ4hn9t8/7Ucoh6ZYYSsVnwtvvrmzMsC1z/0CgYEAynOC\ +v0O+FC5MI+p6HQXdK8JWNecIMEoat5RpmF6nvYSRmHliggoeAV5Of7b6Y0JBRgGm\ ++wECWCKMfaJ1BdCOncci+YkLguSBeJGbDkr65En/zzPxtuvYqcg05x50RWdbLQ5N\ +PF6FHSC8FILpfpJ5f/W8rfNNmU4eTKS4DxUr4r8CgYEA4vfqoO48ovYLtGetEFm1\ +uEP2ZqO0HmCeENOOulYk7pZrgwLmyekMoy2+Ye1daiGt6vGpLvNbn7ievS1cRKbJ\ +5Vp7tOTditmpww0GuftCTcmo5lR6IcLZS6smu6w2Ju3WHpVJ7r+JpRpkgiRjNTle\ +pVzMESOv6LXi2wCo8IA2EkECgYAOyzQRr+yS4vMzaK31svj/epr8I17I0JF1OsYg\ +mUIeqjJNdwlIwV6B8RdBY+iWGkBU0kgWbXNzZ0rm31k3zI6vXt7iZy5NKU+AtPsk\ +pzwANJwZ0wzltgRGG9gpz2Lls3DJMRNZxvppL3wu74YKdr+kJxvbhjz0Z+304dCF\ +YaGsVwKBgA6KSf1pPD93W/v5tV0WnhBZGKb3sX34JLQoCJPS5w6nTjHnuwpP9g0K\ +C8HXKULXuX/rb/gz99PNcPQ9GqB0Rw/ho1KhO3VLJjBiSh/hiASKuFGs2y59UXYt\ +mvqX3jAqi6ksGD5WPG6G2CdL/n30e5/lc10hq7SiwV7z9njW/8Pu\ +-----END RSA PRIVATE KEY----- diff --git a/deployment/src/test/resources/application.properties b/deployment/src/test/resources/application.properties index 77cb475d..5979b743 100644 --- a/deployment/src/test/resources/application.properties +++ b/deployment/src/test/resources/application.properties @@ -1,30 +1 @@ -quarkus.github-app.app-id=88937 -quarkus.github-app.app-name=quarkus-github-app-test -quarkus.github-app.webhook-secret=cs5WKyOlY6go0E1RbkAOf0jq5K4KWBcP -quarkus.github-app.private-key=-----BEGIN RSA PRIVATE KEY-----\ -MIIEowIBAAKCAQEAtsCKYkMzgqSsbkcPThTjeYnd6r5RAS4q5SyiOyIf34nYH5D0\ -jy8Dlt1s8u69KmBoM9Neesqf2Yh80b/UNUtea9knpgR4ME+MIg1LdsLnUWoZuPBl\ -lLaMfwRkN4+ZbTJ7Uo98UUlxoTcCjZVzopSoIazuUF5u+01sx6QEcHB312s42FVL\ -gkd8T36wvIywseOPKr2oyCMQ2AdcxL/cEHwx2hcQAe+eTipsxNy4atIhbDWrML5W\ -v7cYlyn9/sKgxkXtW3eInP3VI3FS+IH+cjwO4FS6ez8TT6USfaCjDb4LgdEKt/de\ -Ds4TbqwM2vjqedLNBhE7t4V2Uf3STdFq+cKHwwIDAQABAoIBAE07MUA1hh8/2F8C\ -SMWGrls+mDoME8+b4yTWp/i1gyLE7kDo0XFxPOMU0GYZ3nd6Jo9AVD0wRD16IMXD\ -e7rKDy0kqEzQtroz49TAKZQW6grN+/DcJxGh094ZzQBt/zjWjKdnW/I+R3cJ+Fo9\ -PpEGoccZfd0ZC23IWqBEAFxEK2Eth7CbJW5eMJElyqSZa9jiF6wdnryH4Xww38iE\ -zv5tL2Ieg03lxj0mdeyzFyIzJTk3PEAFLIjIiducIhSWyJHltpKQEZ3iFMzKfx7l\ -qLIczsyLRouc64+T7lW1PO6SQshHlvc6CtJaHHf98iFMDwdDlSolF/PfNLE5C6lA\ -U0KGUYECgYEA5xcnO9nv58QdcMXobHWethh+a2QTWmEXbE/Lnunqgq+bTgJUbgXR\ -Fi+awb+6GI8lJh16oBbzSRGe2pFQcQa9S84+CnAyVVyras4WC5bcl38q46wh0IRW\ -2sqvJfAI/CJZxgLVceELJ4hn9t8/7Ucoh6ZYYSsVnwtvvrmzMsC1z/0CgYEAynOC\ -v0O+FC5MI+p6HQXdK8JWNecIMEoat5RpmF6nvYSRmHliggoeAV5Of7b6Y0JBRgGm\ -+wECWCKMfaJ1BdCOncci+YkLguSBeJGbDkr65En/zzPxtuvYqcg05x50RWdbLQ5N\ -PF6FHSC8FILpfpJ5f/W8rfNNmU4eTKS4DxUr4r8CgYEA4vfqoO48ovYLtGetEFm1\ -uEP2ZqO0HmCeENOOulYk7pZrgwLmyekMoy2+Ye1daiGt6vGpLvNbn7ievS1cRKbJ\ -5Vp7tOTditmpww0GuftCTcmo5lR6IcLZS6smu6w2Ju3WHpVJ7r+JpRpkgiRjNTle\ -pVzMESOv6LXi2wCo8IA2EkECgYAOyzQRr+yS4vMzaK31svj/epr8I17I0JF1OsYg\ -mUIeqjJNdwlIwV6B8RdBY+iWGkBU0kgWbXNzZ0rm31k3zI6vXt7iZy5NKU+AtPsk\ -pzwANJwZ0wzltgRGG9gpz2Lls3DJMRNZxvppL3wu74YKdr+kJxvbhjz0Z+304dCF\ -YaGsVwKBgA6KSf1pPD93W/v5tV0WnhBZGKb3sX34JLQoCJPS5w6nTjHnuwpP9g0K\ -C8HXKULXuX/rb/gz99PNcPQ9GqB0Rw/ho1KhO3VLJjBiSh/hiASKuFGs2y59UXYt\ -mvqX3jAqi6ksGD5WPG6G2CdL/n30e5/lc10hq7SiwV7z9njW/8Pu\ ------END RSA PRIVATE KEY----- \ No newline at end of file +quarkus.github-app.app-name=quarkus-github-app-test \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/attributes.adoc b/docs/modules/ROOT/pages/includes/attributes.adoc deleted file mode 100644 index 9eb92e51..00000000 --- a/docs/modules/ROOT/pages/includes/attributes.adoc +++ /dev/null @@ -1,7 +0,0 @@ -:quarkus-version: 2.12.0.Final -:quarkus-github-app-version: 1.12.0 - -:github-api-javadoc-root-url: https://github-api.kohsuke.org/apidocs/org/kohsuke/github -:github-reference-documentation-root-url: https://docs.github.com/en/free-pro-team@latest/developers - -:command-airline-examples-dir: ./../examples/command/airline/ \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-github-app.adoc b/docs/modules/ROOT/pages/includes/quarkus-github-app.adoc index eef34ff7..6f15d33b 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-github-app.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-github-app.adoc @@ -14,11 +14,12 @@ a| [[quarkus-github-app_quarkus.github-app.app-id]]`link:#quarkus-github-app_qua [.description] -- -The numeric application id provided by GitHub. +The numeric application id provided by GitHub. + Optional for tests, but mandatory in production and dev mode. Environment variable: `+++QUARKUS_GITHUB_APP_APP_ID+++` --|string -|required icon:exclamation-circle[title=Configuration property is required] +| a| [[quarkus-github-app_quarkus.github-app.app-name]]`link:#quarkus-github-app_quarkus.github-app.app-name[quarkus.github-app.app-name]` @@ -48,12 +49,13 @@ a| [[quarkus-github-app_quarkus.github-app.private-key]]`link:#quarkus-github-ap [.description] -- -The RSA private key. +The RSA private key. + Optional for tests, but mandatory in production and dev mode. Environment variable: `+++QUARKUS_GITHUB_APP_PRIVATE_KEY+++` --|link:https://docs.oracle.com/javase/8/docs/api/java/security/PrivateKey.html[PrivateKey] -|required icon:exclamation-circle[title=Configuration property is required] +| a| [[quarkus-github-app_quarkus.github-app.webhook-secret]]`link:#quarkus-github-app_quarkus.github-app.webhook-secret[quarkus.github-app.webhook-secret]` diff --git a/docs/modules/ROOT/pages/testing.adoc b/docs/modules/ROOT/pages/testing.adoc index a831d144..62c5a7f2 100644 --- a/docs/modules/ROOT/pages/testing.adoc +++ b/docs/modules/ROOT/pages/testing.adoc @@ -37,42 +37,6 @@ Add the following dependency to your `deployment` module: ---- -== Configure the application for tests - -Add a fake application ID and private key to your `application.properties`, just for tests: - -[source,properties] ------- -%test.quarkus.github-app.app-id=0 -%test.quarkus.github-app.private-key=-----BEGIN RSA PRIVATE KEY-----\ -MIIEogIBAAKCAQEA30YvyuZAd+kGDT0nm/XAa93CqsDvC/iYOc4KsKsfBQs1MWjH\ -royuVDfQj2fJvueFnOgZApM3viaCz188D/j3tUMNByIKOfMLiEm/R1tqe7Q6xRRn\ -uwpfT+wv+/x4cNvPxTscwo43LVR9Pno71UfZZywnYN03GS71ttNCiiBKXwCSnHez\ -/t79iAmMnym7ViNsKzA0aS5EwAw9A3GeTnxpRef0y0vDNE2aXBNCe+f1ZnFq1Fhe\ -PJIlKs/qlM136A2co+WRaPghacZJMuwQr1vajuMSBjMEroIPOfSG3x3Oitvnukjp\ -EwuhXjmZeaLc+60rYaMRwf+bje8KmaAVOMWkHQIDAQABAoIBAA+d8SnYARpiCjJS\ -3Lpj7hmdYUhgRlgoAz3H06eX0IuhxQ63rX/gBzGM1eGx+MKJnybidR1g/r0mJHAs\ -0R6s42aiUf71upFjFqNpxR9QnZoZeSLf0oGasB/+/Tw65JHATkAVamWRXPqmtjvw\ -gM7iP6qfxAFad8gjKLyo+jZ/G7SZTCMwnp+sRynirNpycxaAn/xK6Pe43+nyQVWT\ -E0J8bvCzrFD47CM5zZaBQlLWTMjY4Rr3U6BMTGwQWJzGkeGn+2JsHVUch0k7+NRa\ -e3FKjT+57dZqQTnGPVSpBFWEXVO9KLEuLBLyRx0348TZBHzIM9IigN4QS2AaWTJw\ -1kp3VWECgYEA/3P/nsL+RL/yqYvENZ7XqEkXRNH6YHOe8h/lFoYHStCl9y0T8O+z\ -ooJq9hEq7QcYs2bHvBWj8B9he7+bZ5ZOMAM6oIgrgB5FzSvL7JzXhEdONxe/j2TI\ -GbQuC+NxdJtx4Y6yF9Lrb1UyKX+HzR4de+v6b5hER7x8x4gQn1sCYmsCgYEA38CN\ -bTtE3RKY98m33a1Cd6hNXHSyy5GOK5/XGDn0XoGfFe5YJnnh2lia2V4xqUH9d1Mu\ -bB0bEUhfbac5SX5SIW+NBVxzehqfMkrZj/rzN8Wd7TrYAHSldSMhkPTuwuuzfnHL\ -sJLe2gyoqq+sooeE7eCH2fpPIN0wg5U+jc60hZcCgYBHtmrGSPtUlYYr7p6wZt0n\ -0w0DNudQ+GRgmG+ZeRrG9/f/gdodQ01si6w3U+53CAz5IBtmQ7T4Dfcx5EJePCXK\ -+L0Wn+OGXfk+ddMTo5wk+FeOw831FVfPT3O1xq3tDE5WAdchNQb/BC3G1JRtEs04\ -IrD1bwuMD+//m8T+12+97QKBgDko0XhEGdV3+MfkKiphJoe24Pxre3lxl6YhUSuJ\ -Mpop9t/9YVuC62WCGRzKaVlZ2ExxXXyU+uMxX999Rq81q/mKq7Xg5kcdIeoRIP8d\ -FqD6xNtjmuaS5enErcCAMbZtzA7TNzvGaVO+xB/GfQ2QHS8/mrTesvQsTUZwC+ji\ -E0/FAoGATJvuAfgy9uiKR7za7MigYVacE0u4aD1sF7v6D4AFqBOGquPQQhePSdz9\ -G/UUwySoo+AQ+rd2EPhyexjqXBhRGe+EDGFVFivaQzTT8/5bt/VddbTcw2IpmXYj\ -LW6V8BbcP5MRhd2JQSRh16nWwSQJ2BdpUZFwayEEQ6UcrMfqvA0=\ ------END RSA PRIVATE KEY----- ------- - == Add event payloads to the test resources When you <>, diff --git a/integration-tests/testing-framework/src/main/resources/application.properties b/integration-tests/testing-framework/src/main/resources/application.properties index a7e49b2f..99a3a300 100644 --- a/integration-tests/testing-framework/src/main/resources/application.properties +++ b/integration-tests/testing-framework/src/main/resources/application.properties @@ -1,30 +1 @@ -quarkus.application.name=testing-framework-test-app - -%test.quarkus.github-app.app-id=0 -%test.quarkus.github-app.private-key=-----BEGIN RSA PRIVATE KEY-----\ -MIIEogIBAAKCAQEA30YvyuZAd+kGDT0nm/XAa93CqsDvC/iYOc4KsKsfBQs1MWjH\ -royuVDfQj2fJvueFnOgZApM3viaCz188D/j3tUMNByIKOfMLiEm/R1tqe7Q6xRRn\ -uwpfT+wv+/x4cNvPxTscwo43LVR9Pno71UfZZywnYN03GS71ttNCiiBKXwCSnHez\ -/t79iAmMnym7ViNsKzA0aS5EwAw9A3GeTnxpRef0y0vDNE2aXBNCe+f1ZnFq1Fhe\ -PJIlKs/qlM136A2co+WRaPghacZJMuwQr1vajuMSBjMEroIPOfSG3x3Oitvnukjp\ -EwuhXjmZeaLc+60rYaMRwf+bje8KmaAVOMWkHQIDAQABAoIBAA+d8SnYARpiCjJS\ -3Lpj7hmdYUhgRlgoAz3H06eX0IuhxQ63rX/gBzGM1eGx+MKJnybidR1g/r0mJHAs\ -0R6s42aiUf71upFjFqNpxR9QnZoZeSLf0oGasB/+/Tw65JHATkAVamWRXPqmtjvw\ -gM7iP6qfxAFad8gjKLyo+jZ/G7SZTCMwnp+sRynirNpycxaAn/xK6Pe43+nyQVWT\ -E0J8bvCzrFD47CM5zZaBQlLWTMjY4Rr3U6BMTGwQWJzGkeGn+2JsHVUch0k7+NRa\ -e3FKjT+57dZqQTnGPVSpBFWEXVO9KLEuLBLyRx0348TZBHzIM9IigN4QS2AaWTJw\ -1kp3VWECgYEA/3P/nsL+RL/yqYvENZ7XqEkXRNH6YHOe8h/lFoYHStCl9y0T8O+z\ -ooJq9hEq7QcYs2bHvBWj8B9he7+bZ5ZOMAM6oIgrgB5FzSvL7JzXhEdONxe/j2TI\ -GbQuC+NxdJtx4Y6yF9Lrb1UyKX+HzR4de+v6b5hER7x8x4gQn1sCYmsCgYEA38CN\ -bTtE3RKY98m33a1Cd6hNXHSyy5GOK5/XGDn0XoGfFe5YJnnh2lia2V4xqUH9d1Mu\ -bB0bEUhfbac5SX5SIW+NBVxzehqfMkrZj/rzN8Wd7TrYAHSldSMhkPTuwuuzfnHL\ -sJLe2gyoqq+sooeE7eCH2fpPIN0wg5U+jc60hZcCgYBHtmrGSPtUlYYr7p6wZt0n\ -0w0DNudQ+GRgmG+ZeRrG9/f/gdodQ01si6w3U+53CAz5IBtmQ7T4Dfcx5EJePCXK\ -+L0Wn+OGXfk+ddMTo5wk+FeOw831FVfPT3O1xq3tDE5WAdchNQb/BC3G1JRtEs04\ -IrD1bwuMD+//m8T+12+97QKBgDko0XhEGdV3+MfkKiphJoe24Pxre3lxl6YhUSuJ\ -Mpop9t/9YVuC62WCGRzKaVlZ2ExxXXyU+uMxX999Rq81q/mKq7Xg5kcdIeoRIP8d\ -FqD6xNtjmuaS5enErcCAMbZtzA7TNzvGaVO+xB/GfQ2QHS8/mrTesvQsTUZwC+ji\ -E0/FAoGATJvuAfgy9uiKR7za7MigYVacE0u4aD1sF7v6D4AFqBOGquPQQhePSdz9\ -G/UUwySoo+AQ+rd2EPhyexjqXBhRGe+EDGFVFivaQzTT8/5bt/VddbTcw2IpmXYj\ -LW6V8BbcP5MRhd2JQSRh16nWwSQJ2BdpUZFwayEEQ6UcrMfqvA0=\ ------END RSA PRIVATE KEY----- +quarkus.application.name=testing-framework-test-app \ No newline at end of file diff --git a/runtime/src/main/java/io/quarkiverse/githubapp/runtime/config/GitHubAppRuntimeConfig.java b/runtime/src/main/java/io/quarkiverse/githubapp/runtime/config/GitHubAppRuntimeConfig.java index b60c020e..9382f94c 100644 --- a/runtime/src/main/java/io/quarkiverse/githubapp/runtime/config/GitHubAppRuntimeConfig.java +++ b/runtime/src/main/java/io/quarkiverse/githubapp/runtime/config/GitHubAppRuntimeConfig.java @@ -15,9 +15,11 @@ public class GitHubAppRuntimeConfig { /** * The numeric application id provided by GitHub. + *

+ * Optional for tests, but mandatory in production and dev mode. */ @ConfigItem - public String appId; + public Optional appId; /** * The GitHub name of the application. @@ -35,10 +37,12 @@ public class GitHubAppRuntimeConfig { /** * The RSA private key. + *

+ * Optional for tests, but mandatory in production and dev mode. */ @ConfigItem @ConvertWith(PrivateKeyConverter.class) - public PrivateKey privateKey; + public Optional privateKey; /** * The webhook secret if defined in the GitHub UI. diff --git a/runtime/src/main/java/io/quarkiverse/githubapp/runtime/github/GitHubService.java b/runtime/src/main/java/io/quarkiverse/githubapp/runtime/github/GitHubService.java index 1a7d56ad..8adb39c7 100644 --- a/runtime/src/main/java/io/quarkiverse/githubapp/runtime/github/GitHubService.java +++ b/runtime/src/main/java/io/quarkiverse/githubapp/runtime/github/GitHubService.java @@ -2,11 +2,15 @@ import java.io.IOException; import java.security.GeneralSecurityException; +import java.security.PrivateKey; import java.time.temporal.ChronoUnit; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; import javax.inject.Inject; import org.kohsuke.github.GHAppInstallationToken; @@ -21,6 +25,9 @@ import io.quarkiverse.githubapp.GitHubClientProvider; import io.quarkiverse.githubapp.runtime.config.GitHubAppRuntimeConfig; import io.quarkiverse.githubapp.runtime.signing.JwtTokenCreator; +import io.quarkus.runtime.LaunchMode; +import io.quarkus.runtime.StartupEvent; +import io.quarkus.runtime.configuration.ConfigurationException; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClientBuilder; @@ -32,14 +39,17 @@ public class GitHubService implements GitHubClientProvider { private final GitHubAppRuntimeConfig gitHubAppRuntimeConfig; - private final JwtTokenCreator jwtTokenCreator; + private final JwtTokenProvider jwtTokenProvider; private final LoadingCache installationTokenCache; + @Inject + LaunchMode launchMode; + @Inject public GitHubService(GitHubAppRuntimeConfig gitHubAppRuntimeConfig, JwtTokenCreator jwtTokenCreator) { this.gitHubAppRuntimeConfig = gitHubAppRuntimeConfig; - this.jwtTokenCreator = jwtTokenCreator; + this.jwtTokenProvider = new JwtTokenProvider(gitHubAppRuntimeConfig, jwtTokenCreator); this.installationTokenCache = Caffeine.newBuilder() .maximumSize(50) .expireAfter(new Expiry() { @@ -69,6 +79,20 @@ public long expireAfterRead(Long installationId, CachedInstallationToken cachedI .build(new CreateInstallationToken()); } + public void init(@Observes StartupEvent startupEvent) throws IOException { + switch (launchMode) { + case TEST: + // If some client config is missing, we'll fail later, and only if tests attempt to retrieve the client. + break; + case NORMAL: + case DEVELOPMENT: + default: + // If some client config is missing, we'll fail on startup. + jwtTokenProvider.checkConfig(); + break; + } + } + @Override public GitHub getInstallationClient(long installationId) { try { @@ -179,8 +203,7 @@ private GitHub createApplicationGitHub() { String jwtToken; try { - // maximum TTL is 10 minutes - jwtToken = jwtTokenCreator.createJwtToken(gitHubAppRuntimeConfig.appId, gitHubAppRuntimeConfig.privateKey, 540); + jwtToken = jwtTokenProvider.createJwtToken(); } catch (GeneralSecurityException | IOException e) { throw new IllegalStateException("Unable to generate the JWT token", e); } @@ -195,4 +218,45 @@ private GitHub createApplicationGitHub() { throw new IllegalStateException("Unable to create a GitHub client for the application", e); } } + + private static class JwtTokenProvider { + private final String appId; + private final PrivateKey privateKey; + private final Set missingPropertyKeys = new HashSet<>(); + private final JwtTokenCreator jwtTokenCreator; + + public JwtTokenProvider(GitHubAppRuntimeConfig gitHubAppRuntimeConfig, JwtTokenCreator jwtTokenCreator) { + this.jwtTokenCreator = jwtTokenCreator; + if (gitHubAppRuntimeConfig.appId.isPresent()) { + appId = gitHubAppRuntimeConfig.appId.get(); + } else { + appId = null; + missingPropertyKeys.add("quarkus.github-app.app-id"); + } + if (gitHubAppRuntimeConfig.privateKey.isPresent()) { + privateKey = gitHubAppRuntimeConfig.privateKey.get(); + } else { + privateKey = null; + missingPropertyKeys.add("quarkus.github-app.private-key"); + } + } + + public String createJwtToken() throws GeneralSecurityException, IOException { + checkConfig(); + // maximum TTL is 10 minutes + return jwtTokenCreator.createJwtToken(appId, privateKey, 540); + } + + public void checkConfig() { + if (!missingPropertyKeys.isEmpty()) { + throw new ConfigurationException( + "Missing value for configuration properties " + missingPropertyKeys + "." + + " This configuration is necessary to create the GitHub clients." + + " It is optional only in tests, if GitHub clients are being mocked using quarkus-github-app-testing" + + " (see https://quarkiverse.github.io/quarkiverse-docs/quarkus-github-app/dev/testing.html).", + missingPropertyKeys); + } + } + + } }