From f03ad150bb1c76fb56b51a6c11a855cd956302e6 Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Wed, 20 Jan 2021 16:23:06 +0100 Subject: [PATCH 1/5] Run tabia as a Github App --- .env.example | 2 ++ cmd/cmd_github.go | 54 +++++++++++++++++++++++++++++++++++++++++------ go.mod | 2 ++ go.sum | 38 +++++++++++++++++++++++++++++++++ lib/github/app.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 lib/github/app.go diff --git a/.env.example b/.env.example index 9b39fc8..f67d67b 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,8 @@ export TABIA_BITBUCKET_USER= export TABIA_BITBUCKET_TOKEN= export TABIA_GITHUB_USER= export TABIA_GITHUB_TOKEN= +export TABIA_GITHUB_APP_INTEGRATION_ID= +export TABIA_GITHUB_APP_PRIVATE_KEY= export TABIA_GITLAB_INSTANCE=https://gitlab.your.instance.com/ export TABIA_GITLAB_TOKEN= # when requests should go via proxy diff --git a/cmd/cmd_github.go b/cmd/cmd_github.go index fc878bd..5b404c2 100644 --- a/cmd/cmd_github.go +++ b/cmd/cmd_github.go @@ -26,7 +26,21 @@ func createGithub() *cli.Command { Aliases: []string{"t"}, Usage: "Calls the api using the given `TOKEN`", EnvVars: []string{"TABIA_GITHUB_TOKEN"}, - Required: true, + Required: false, + }, + &cli.StringFlag{ + Name: "integration-id", + Aliases: []string{"app-id"}, + Usage: "Authenticates to Github using the given `APP_INTEGRATION_ID`", + EnvVars: []string{"TABIA_GITHUB_APP_INTEGRATION_ID"}, + Required: false, + }, + &cli.PathFlag{ + Name: "private-key", + Usage: "Authenticates to Github using the given `APP_PRIVATE_KEY`", + EnvVars: []string{"TABIA_GITHUB_APP_PRIVATE_KEY"}, + Required: false, + TakesFile: true, }, &cli.BoolFlag{ Name: "verbose", @@ -130,16 +144,32 @@ func createGithub() *cli.Command { } } -func newGithubClient(c *cli.Context) *github.Client { +func newGithubClient(c *cli.Context) (*github.Client, error) { verbose := c.Bool("verbose") - token := c.String("token") var ghWriter io.Writer if verbose { ghWriter = c.App.Writer } - return github.NewClientWithTokenAuth(token, ghWriter) + if c.IsSet("integration-id") && c.IsSet("private-key") { + integrationID := c.Int64("integration-id") + privateKey := c.Path("private-key") + + privateKeyBytes, err := ioutil.ReadFile(privateKey) + if err != nil { + return nil, err + } + client, err := github.NewClientWithAppAuth(integrationID, string(privateKeyBytes), ghWriter) + return client, nil + } + + if !c.IsSet("token") { + return nil, fmt.Errorf("no `integration-id` and `private-key` or `token` provided") + } + + token := c.String("token") + return github.NewClientWithTokenAuth(token, ghWriter), nil } func githubMembers(c *cli.Context) error { @@ -147,7 +177,11 @@ func githubMembers(c *cli.Context) error { format := c.String("format") filter := c.String("filter") - client := newGithubClient(c) + client, err := newGithubClient(c) + if err != nil { + return err + } + ctx, cancel := context.WithCancel(c.Context) defer cancel() @@ -198,7 +232,10 @@ func githubRepositories(c *cli.Context) error { format := c.String("format") filter := c.String("filter") - client := newGithubClient(c) + client, err := newGithubClient(c) + if err != nil { + return err + } ctx, cancel := context.WithCancel(c.Context) defer cancel() @@ -274,7 +311,10 @@ func githubContents(c *cli.Context) error { filePath := c.String("file") output := c.Path("output") - client := newGithubClient(c) + client, err := newGithubClient(c) + if err != nil { + return err + } ctx, cancel := context.WithCancel(c.Context) defer cancel() diff --git a/go.mod b/go.mod index 4a57401..46ef00b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,9 @@ require ( github.com/antonmedv/expr v1.8.9 github.com/google/go-github/v33 v33.0.0 github.com/goreleaser/goreleaser v0.157.0 + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 github.com/hashicorp/go-cleanhttp v0.5.2 + github.com/palantir/go-githubapp v0.6.0 github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index 3428b97..93291ef 100644 --- a/go.sum +++ b/go.sum @@ -94,6 +94,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v0.0.0-20180330214955-e67964b4021a/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0 h1:uCRZZOdMQ0TZPHYTdYpoC0bLYJKPEHPUJ8MeAa51lNU= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= @@ -122,6 +123,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexedwards/scs v1.4.1/go.mod h1:JRIFiXthhMSivuGbxpzUa0/hT5rz2hpyw61Bmd+S1bg= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -147,14 +149,18 @@ github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.36.1 h1:rDgSL20giXXu48Ycx6Qa4vWaNTVTltUl6vA73ObCSVk= github.com/aws/aws-sdk-go v1.36.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/bluekeyes/hatpear v0.0.0-20180714193905-ffb42d5bb417/go.mod h1:D+WOahrNtu6OK0KiVoXY9h5j7IcEs5LYke+zJkMBsKg= github.com/bombsimon/wsl/v3 v3.1.0 h1:E5SRssoBgtVFPcYWUOFJEcgaySgdtTNYzsSKDOY7ss8= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/bradleyfalzon/ghinstallation v1.1.1 h1:pmBXkxgM1WeF8QYvDLT5kuQiHMcmf+X015GI0KM/E3I= +github.com/bradleyfalzon/ghinstallation v1.1.1/go.mod h1:vyCmHTciHx/uuyN82Zc3rXN3X2KTK8nUTCrTMwAhcug= github.com/caarlos0/ctrlc v1.0.0 h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ= @@ -180,16 +186,20 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/crewjam/httperr v0.0.0-20190612203328-a946449404da/go.mod h1:+rmNIXRvYMqLQeR4DHyTvs6y0MEMymTz4vyFpFkKTPs= +github.com/crewjam/saml v0.3.2-0.20191206212704-861266e3a689/go.mod h1:fxbjgoFRea91JEzfcATb14uB+XPW1H88n0feRzehDeg= github.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg= github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4= github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= @@ -349,6 +359,9 @@ github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= +github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= +github.com/google/go-github/v29 v29.0.3 h1:IktKCTwU//aFHnpA+2SLIi7Oo9uhAzgsdZNbcAqhgdc= +github.com/google/go-github/v29 v29.0.3/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= github.com/google/go-github/v33 v33.0.0 h1:qAf9yP0qc54ufQxzwv+u9H0tiVOnPJxo0lI/JXqw3ZM= github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= @@ -408,6 +421,8 @@ github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0 github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -434,6 +449,8 @@ github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -596,6 +613,9 @@ github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U= github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/palantir/go-baseapp v0.2.0/go.mod h1:7rEjgYzWbHLLuY+mV2iJthxTddEc6aO+kFYsjDKNmEs= +github.com/palantir/go-githubapp v0.6.0 h1:FjjoD5Enh8DoEdW8ofZscKms7mHXs6gfNvdKlJ55TGY= +github.com/palantir/go-githubapp v0.6.0/go.mod h1:i8KvEdQ5AF0wZg6C+GFXBTSTpL1zAuObjiQbdo86Kbc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -631,6 +651,9 @@ github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwq github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c h1:+gtJ/Pwj2dgUGlZgTrNFqajGYKZQc7Piqus/S6DK9CE= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/tview v0.0.0-20200219210816-cd38d7432498/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -638,6 +661,11 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.9.1/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8= +github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= +github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7/go.mod h1:Oz4y6ImuOQZxynhbSXk7btjEfNBtGlj2dcaOvXl2FSM= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc85CVZro= @@ -658,10 +686,12 @@ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqP github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa h1:jozR3igKlnYCj9IVHOVump59bp07oIRoLQ/CcjMYIUA= github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= @@ -773,6 +803,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/zenazn/goji v0.9.1-0.20160507202103-64eb34159fe5/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -787,6 +819,8 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= gocloud.dev v0.22.0 h1:psFb4EJ+bF9bjns7XR3n3tMMMB1LNs97YURcyh4oVWM= gocloud.dev v0.22.0/go.mod h1:z3jKIQ0Es9LALVZFQ3wOvwqAsSLq1R5c/2RdmghDucw= +goji.io v2.0.0+incompatible/go.mod h1:sbqFwrtqZACxLBTQcdgVjFh54yGVCvwq8+w49MVMMIk= +goji.io v2.0.2+incompatible/go.mod h1:sbqFwrtqZACxLBTQcdgVjFh54yGVCvwq8+w49MVMMIk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -796,6 +830,8 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -924,6 +960,7 @@ golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -993,6 +1030,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/lib/github/app.go b/lib/github/app.go new file mode 100644 index 0000000..b0db3a3 --- /dev/null +++ b/lib/github/app.go @@ -0,0 +1,54 @@ +package github + +import ( + "io" + "net/http" + "time" + + "github.com/gregjones/httpcache" + "github.com/palantir/go-githubapp/githubapp" + + "github.com/philips-labs/tabia/lib/transport" +) + +// NewClientWithAppAuth creates a new client that authenticates using an app integration ID +// and a app private key +func NewClientWithAppAuth(integrationID int64, privateKey string, writer io.Writer) (*Client, error) { + config := new(githubapp.Config) + config.App.IntegrationID = integrationID + config.App.PrivateKey = privateKey + config.V3APIURL = "https://api.github.com/" + config.V4APIURL = "https://api.github.com/graphql" + + cc, err := githubapp.NewDefaultCachingClientCreator( + *config, + githubapp.WithClientUserAgent("tabia"), + githubapp.WithClientTimeout(3*time.Second), + githubapp.WithClientCaching(false, func() httpcache.Cache { return httpcache.NewMemoryCache() }), + githubapp.WithClientMiddleware(ClientLogging(writer)), + ) + + client, err := cc.NewAppV4Client() + if err != nil { + return nil, err + } + restClient, err := cc.NewAppClient() + if err != nil { + return nil, err + } + + return &Client{nil, restClient, client}, nil +} + +func ClientLogging(writer io.Writer) githubapp.ClientMiddleware { + return func(next http.RoundTripper) http.RoundTripper { + if writer != nil { + return transport.TeeRoundTripper{ + RoundTripper: next, + Writer: writer, + } + } + + return next + } +} From 93c8600ed530ad4f59752a79a6683c447d84903c Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Wed, 20 Jan 2021 16:30:06 +0100 Subject: [PATCH 2/5] Test App initialization using non existing private key --- lib/github/app_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 lib/github/app_test.go diff --git a/lib/github/app_test.go b/lib/github/app_test.go new file mode 100644 index 0000000..dd905a0 --- /dev/null +++ b/lib/github/app_test.go @@ -0,0 +1,20 @@ +package github_test + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/philips-labs/tabia/lib/github" +) + +func TestAppClient(t *testing.T) { + assert := assert.New(t) + + var buf strings.Builder + integrationID := int64(12345) + client, err := github.NewClientWithAppAuth(integrationID, "/path/to/rsa-private-key.pem", &buf) + assert.Error(err) + assert.Nil(client) +} From 2e996ff56c794fb2e9485c9dfacc453ee50f2ab5 Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Wed, 20 Jan 2021 18:43:13 +0100 Subject: [PATCH 3/5] Improve documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2790494..49bd3a3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Tabia means characteristic in Swahili. Tabia is giving us insights on the charac ## Setup -Copy `.env.example` to `.env` and fill out the bitbucket token. This environment variable is read by the CLI and tests. Also vscode will read the variable when running tests or starting debugger. +Copy `.env.example` to `.env` and fill out the credentials. This environment variable is read by the CLI and tests. Also vscode will read the variable when running tests or starting debugger. ```bash cp .env.example .env From 6c79792054d8c6e5a04e69d2a9683f9d295478e8 Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Wed, 20 Jan 2021 20:04:30 +0100 Subject: [PATCH 4/5] Utilize an AppInstallation token to get the correct permissions --- README.md | 12 ++++++++++++ cmd/cmd_github.go | 4 +++- lib/github/app.go | 19 +++++++++++++++---- lib/github/app_test.go | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 49bd3a3..92f0fcf 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,18 @@ bin/tabia github --help bin/tabia github repositories --help ``` +#### Authentication + +Please note when using Github Authentication there are 2 options to authenticate. + +1. Authenticate as a Github App (your app will have to be installed in the organization) + - integration-id + - private-key +2. Authenticate using a Personal Access Token + - token + +> :warning: When authenticating as a *GitHub App* please be informed you can only fetch information from **one** organization at a time as the client will be bound to that organizations App installation. To support multiple organizations we require a refactor using a Github client per organization. + ### Output - Grimoirelab To expose the repositories in [Grimoirelab projects.json](https://github.com/chaoss/grimoirelab-sirmordred#projectsjson-) format, you can optionally provide a json file to map repositories to projects. By default the project will be mapped to the owner of the repository. Anything not matching the rules will fall back to this default. diff --git a/cmd/cmd_github.go b/cmd/cmd_github.go index 5b404c2..a55e0af 100644 --- a/cmd/cmd_github.go +++ b/cmd/cmd_github.go @@ -160,7 +160,9 @@ func newGithubClient(c *cli.Context) (*github.Client, error) { if err != nil { return nil, err } - client, err := github.NewClientWithAppAuth(integrationID, string(privateKeyBytes), ghWriter) + org := append(c.StringSlice("owner"), c.StringSlice("organization")...) + + client, err := github.NewClientWithAppAuth(integrationID, string(privateKeyBytes), org[0], ghWriter) return client, nil } diff --git a/lib/github/app.go b/lib/github/app.go index b0db3a3..f1384b5 100644 --- a/lib/github/app.go +++ b/lib/github/app.go @@ -1,6 +1,8 @@ package github import ( + "context" + "fmt" "io" "net/http" "time" @@ -13,7 +15,7 @@ import ( // NewClientWithAppAuth creates a new client that authenticates using an app integration ID // and a app private key -func NewClientWithAppAuth(integrationID int64, privateKey string, writer io.Writer) (*Client, error) { +func NewClientWithAppAuth(integrationID int64, privateKey, organization string, writer io.Writer) (*Client, error) { config := new(githubapp.Config) config.App.IntegrationID = integrationID config.App.PrivateKey = privateKey @@ -23,20 +25,29 @@ func NewClientWithAppAuth(integrationID int64, privateKey string, writer io.Writ cc, err := githubapp.NewDefaultCachingClientCreator( *config, githubapp.WithClientUserAgent("tabia"), - githubapp.WithClientTimeout(3*time.Second), + githubapp.WithClientTimeout(10*time.Second), githubapp.WithClientCaching(false, func() httpcache.Cache { return httpcache.NewMemoryCache() }), githubapp.WithClientMiddleware(ClientLogging(writer)), ) - client, err := cc.NewAppV4Client() + appClient, err := cc.NewAppClient() if err != nil { return nil, err } - restClient, err := cc.NewAppClient() + installation, _, err := appClient.Apps.FindOrganizationInstallation(context.Background(), organization) if err != nil { return nil, err } + fmt.Println(installation) + client, err := cc.NewInstallationV4Client(*installation.ID) + if err != nil { + return nil, err + } + restClient, err := cc.NewInstallationClient(*installation.ID) + if err != nil { + return nil, err + } return &Client{nil, restClient, client}, nil } diff --git a/lib/github/app_test.go b/lib/github/app_test.go index dd905a0..8d7286c 100644 --- a/lib/github/app_test.go +++ b/lib/github/app_test.go @@ -14,7 +14,7 @@ func TestAppClient(t *testing.T) { var buf strings.Builder integrationID := int64(12345) - client, err := github.NewClientWithAppAuth(integrationID, "/path/to/rsa-private-key.pem", &buf) + client, err := github.NewClientWithAppAuth(integrationID, "/path/to/rsa-private-key.pem", "philips-labs", &buf) assert.Error(err) assert.Nil(client) } From a34b1d0a94bbc6b067abeff9a40e24ea2177ff64 Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Fri, 5 Mar 2021 12:06:52 +0100 Subject: [PATCH 5/5] Fix after upgrading to Go 1.16 --- cmd/cmd_github.go | 2 +- cmd/cmd_gitlab.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/cmd_github.go b/cmd/cmd_github.go index a55e0af..272da30 100644 --- a/cmd/cmd_github.go +++ b/cmd/cmd_github.go @@ -156,7 +156,7 @@ func newGithubClient(c *cli.Context) (*github.Client, error) { integrationID := c.Int64("integration-id") privateKey := c.Path("private-key") - privateKeyBytes, err := ioutil.ReadFile(privateKey) + privateKeyBytes, err := os.ReadFile(privateKey) if err != nil { return nil, err } diff --git a/cmd/cmd_gitlab.go b/cmd/cmd_gitlab.go index 86e1565..3b0360e 100644 --- a/cmd/cmd_gitlab.go +++ b/cmd/cmd_gitlab.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "io" - "io/ioutil" + "os" "text/tabwriter" "github.com/urfave/cli/v2" @@ -111,7 +111,7 @@ func gitlabRepositories(c *cli.Context) error { } templateFile := c.Path("template") - tmplContent, err := ioutil.ReadFile(templateFile) + tmplContent, err := os.ReadFile(templateFile) if err != nil { return err }