From 803c94ca37c726f3cdaf6409a08e04989cf044cd Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 17 Oct 2023 21:56:34 -0300 Subject: [PATCH 01/19] feat: add go-bitbucket-v1 --- go.mod | 1 + go.sum | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index a29351b..d512db2 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.12 require ( github.com/Masterminds/sprig/v3 v3.2.2 github.com/PuerkitoBio/goquery v1.8.0 + github.com/gfleury/go-bitbucket-v1 v0.0.0-20230830121038-6e30c5760c87 github.com/gorilla/mux v1.8.0 github.com/mattermost/mattermost-plugin-api v0.0.22 github.com/mattermost/mattermost-server/v6 v6.5.2 diff --git a/go.sum b/go.sum index 2aa338f..5a2f2f8 100644 --- a/go.sum +++ b/go.sum @@ -476,6 +476,10 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/gfleury/go-bitbucket-v1 v0.0.0-20230830121038-6e30c5760c87 h1:aix/N0cwFcyaYksDTa96rcila54zTQ6Nk6yENtgO7yM= +github.com/gfleury/go-bitbucket-v1 v0.0.0-20230830121038-6e30c5760c87/go.mod h1:6saoZ1uJyRD/w4t5Djj8mik5W9cLjSKvba6ZaryV+98= +github.com/gfleury/go-bitbucket-v1/test/bb-mock-server v0.0.0-20230825095122-9bc1711434ab h1:BeG9dDWckFi/p5Gvqq3wTEDXsUV4G6bdvjEHMOT2B8E= +github.com/gfleury/go-bitbucket-v1/test/bb-mock-server v0.0.0-20230825095122-9bc1711434ab/go.mod h1:VssB0kb1cETNaFFC/0mHVCj+7i5TS2xraYq+tl9JLwE= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573/go.mod h1:eBvb3i++NHDH4Ugo9qCvMw8t0mTSctaEa5blJbWcNxs= @@ -1036,6 +1040,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= @@ -1449,8 +1454,9 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= -github.com/yuin/goldmark v1.4.5 h1:4OEQwtW2uLXjEdgnGM3Vg652Pq37X7NOIRzFWb3BzIc= github.com/yuin/goldmark v1.4.5/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1582,6 +1588,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1659,8 +1666,10 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1697,6 +1706,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1822,11 +1832,15 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc= golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1835,8 +1849,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1925,6 +1940,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 18005d5621f6bad3808c54523618ecb713be9a5d Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Mon, 30 Oct 2023 20:46:48 -0300 Subject: [PATCH 02/19] feat: create the bitbucketv1Connect to connect to bitbucket server --- server/plugin.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/server/plugin.go b/server/plugin.go index b41be79..26d9313 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -12,6 +12,7 @@ import ( "strings" "sync" + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/wbrefvem/go-bitbucket" @@ -62,6 +63,9 @@ type Plugin struct { webhookHandler webhook.Webhook router *mux.Router + + // TODO: This can be converted into a generic client + bitbucketClient *BitbucketServerClient } // NewPlugin returns an instance of a Plugin. @@ -78,6 +82,9 @@ func NewPlugin() *Plugin { "settings": p.handleSettings, } + // TODO: This can be converted into a generic client + p.bitbucketClient = NewClientServer() + return p } @@ -105,6 +112,23 @@ func (p *Plugin) bitbucketConnect(token oauth2.Token) *bitbucket.APIClient { return bitbucket.NewAPIClient(configBb) } +// TODO: This method needs to be changed when Modularization is built +func (p *Plugin) bitbucketv1Connect(token oauth2.Token) *bitbucketv1.APIClient { + // get Oauth token source and client + ts := p.getOAuthConfig().TokenSource(context.Background(), &token) + + // setup Oauth context + auth := context.WithValue(context.Background(), bitbucket.ContextOAuth2, ts) + + tc := oauth2.NewClient(auth, ts) + + // create config for bitbucket API + configBb := p.bitbucketClient.NewConfiguration(*p.getConfiguration()) + configBb.HTTPClient = tc + + return bitbucketv1.NewAPIClient(context.Background(), configBb) +} + func (p *Plugin) OnActivate() error { config := p.getConfiguration() From 608e55a31b24ecfc1d1c7c595dba907b94f2d3c8 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Mon, 30 Oct 2023 20:48:40 -0300 Subject: [PATCH 03/19] feat: adding the client_server to create the bitbucket server methods --- server/client_server.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 server/client_server.go diff --git a/server/client_server.go b/server/client_server.go new file mode 100644 index 0000000..af3bed9 --- /dev/null +++ b/server/client_server.go @@ -0,0 +1,26 @@ +package main + +import ( + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" +) + +type BitbucketServerClient struct { + configuration *bitbucketv1.Configuration +} + +func NewClientServer() *BitbucketServerClient { + return &BitbucketServerClient{} +} + +func (c *BitbucketServerClient) NewConfiguration(config Configuration) *bitbucketv1.Configuration { + c.configuration = bitbucketv1.NewConfiguration(config.BitbucketAPISelfHostedURL) + return c.configuration +} + +func (c *BitbucketServerClient) GetCurrentUser() string { + return "" +} + +func (c *BitbucketServerClient) GetMe() { + +} From 02261896bdfc2f635dd40e4d70f7e78087ff429f Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 31 Oct 2023 21:29:30 -0300 Subject: [PATCH 04/19] fix: fixes the ServeHTTP of the plugin --- server/api.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/api.go b/server/api.go index 86df01a..08f1494 100644 --- a/server/api.go +++ b/server/api.go @@ -15,6 +15,7 @@ import ( "golang.org/x/oauth2" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/plugin" ) const ( @@ -154,7 +155,7 @@ func checkPluginRequest(next http.HandlerFunc) http.HandlerFunc { } } -func (p *Plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (p *Plugin) ServeHTTP(_ *plugin.Context, w http.ResponseWriter, r *http.Request) { config := p.getConfiguration() if err := config.IsValid(); err != nil { From 4780f6995b3c36c08f2fc4b0af4fad99fe483c17 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 7 Nov 2023 10:26:11 -0300 Subject: [PATCH 05/19] feat: transfering connect function to client_server and created GetWhoAmI --- server/client_server.go | 68 ++++++++++++++++++++++++++++++++++++----- server/plugin.go | 18 ----------- 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/server/client_server.go b/server/client_server.go index af3bed9..c9a5ea9 100644 --- a/server/client_server.go +++ b/server/client_server.go @@ -1,26 +1,78 @@ package main import ( + "context" + "fmt" + "io" + "net/http" + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" + "github.com/pkg/errors" + "golang.org/x/oauth2" ) type BitbucketServerClient struct { - configuration *bitbucketv1.Configuration + apiClient *bitbucketv1.APIClient + + selfHostedURL string + selfHostedAPIURL string + + token oauth2.Token } func NewClientServer() *BitbucketServerClient { return &BitbucketServerClient{} } -func (c *BitbucketServerClient) NewConfiguration(config Configuration) *bitbucketv1.Configuration { - c.configuration = bitbucketv1.NewConfiguration(config.BitbucketAPISelfHostedURL) - return c.configuration -} +// TODO: This method needs to be changed when Modularization is built +func (c *BitbucketServerClient) Connect(config Configuration, token oauth2.Token, ts oauth2.TokenSource) *BitbucketServerClient { + // setup Oauth context + auth := context.WithValue(context.Background(), bitbucketv1.ContextOAuth2, ts) -func (c *BitbucketServerClient) GetCurrentUser() string { - return "" + tc := oauth2.NewClient(auth, ts) + + // create config for bitbucket API + configBb := bitbucketv1.NewConfiguration(config.BitbucketAPISelfHostedURL) + configBb.HTTPClient = tc + + c.apiClient = bitbucketv1.NewAPIClient(context.Background(), configBb) + c.selfHostedURL = config.BitbucketSelfHostedURL + c.selfHostedAPIURL = config.BitbucketAPISelfHostedURL + c.token = token + + return c } -func (c *BitbucketServerClient) GetMe() { +func (c *BitbucketServerClient) getWhoAmI() (string, error) { + baseUrl := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.selfHostedURL) + + req, err := http.NewRequest("GET", baseUrl, nil) + if err != nil { + return "", err + } + + client := &http.Client{} + + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.token.AccessToken)) + + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return "", errors.Errorf("who am i returned non-200 status code: %d", resp.StatusCode) + } + + user, err := io.ReadAll(resp.Body) + if err != nil { + return "", errors.Wrap(err, "failed to read response") + } + + return string(user), nil +} +func (c *BitbucketServerClient) GetMe() (string, error) { + return c.getWhoAmI() } diff --git a/server/plugin.go b/server/plugin.go index 26d9313..678fa97 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -12,7 +12,6 @@ import ( "strings" "sync" - bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/wbrefvem/go-bitbucket" @@ -112,23 +111,6 @@ func (p *Plugin) bitbucketConnect(token oauth2.Token) *bitbucket.APIClient { return bitbucket.NewAPIClient(configBb) } -// TODO: This method needs to be changed when Modularization is built -func (p *Plugin) bitbucketv1Connect(token oauth2.Token) *bitbucketv1.APIClient { - // get Oauth token source and client - ts := p.getOAuthConfig().TokenSource(context.Background(), &token) - - // setup Oauth context - auth := context.WithValue(context.Background(), bitbucket.ContextOAuth2, ts) - - tc := oauth2.NewClient(auth, ts) - - // create config for bitbucket API - configBb := p.bitbucketClient.NewConfiguration(*p.getConfiguration()) - configBb.HTTPClient = tc - - return bitbucketv1.NewAPIClient(context.Background(), configBb) -} - func (p *Plugin) OnActivate() error { config := p.getConfiguration() From 78359dba242995696e4f8d237ec741d01b596894 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 7 Nov 2023 20:56:27 -0300 Subject: [PATCH 06/19] fix: api tests --- server/api_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/api_test.go b/server/api_test.go index 45b0985..5959923 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -72,7 +72,7 @@ func TestPlugin_ServeHTTP(t *testing.T) { req := test.httpTest.CreateHTTPRequest(test.request) req.Header.Add("Mattermost-User-ID", test.userID) rr := httptest.NewRecorder() - p.ServeHTTP(rr, req) + p.ServeHTTP(&plugin.Context{}, rr, req) test.httpTest.CompareHTTPResponse(rr, test.expectedResponse) }) } @@ -122,7 +122,7 @@ func TestGetToken(t *testing.T) { req := test.httpTest.CreateHTTPRequest(test.request) rr := httptest.NewRecorder() - p.ServeHTTP(rr, req) + p.ServeHTTP(test.context, rr, req) test.httpTest.CompareHTTPResponse(rr, test.expectedResponse) }) From f5ee1bf963ee655b5bf1d52c50aeb2afceee8755 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Wed, 8 Nov 2023 11:20:13 -0300 Subject: [PATCH 07/19] test: simple tests on the client server --- server/client_server_test.go | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 server/client_server_test.go diff --git a/server/client_server_test.go b/server/client_server_test.go new file mode 100644 index 0000000..57afd30 --- /dev/null +++ b/server/client_server_test.go @@ -0,0 +1,63 @@ +package main + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "golang.org/x/oauth2" +) + +func TestGetWhoAmI(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + authHeader := r.Header.Get("Authorization") + if authHeader != "Bearer valid-token" { + w.WriteHeader(http.StatusUnauthorized) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("mocked-user")) + })) + defer server.Close() + + tests := []struct { + name string + token oauth2.Token + expectedResult string + expectedError string + }{ + { + name: "valid token", + token: oauth2.Token{AccessToken: "valid-token"}, + expectedResult: "mocked-user", + expectedError: "", + }, + { + name: "invalid token", + token: oauth2.Token{AccessToken: "invalid-token"}, + expectedResult: "", + expectedError: "who am i returned non-200 status code: 401", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + client := NewClientServer() + client.selfHostedURL = server.URL + client.token = tc.token + + result, err := client.getWhoAmI() + + if tc.expectedError == "" { + assert.NoError(t, err) + assert.Equal(t, tc.expectedResult, result) + } else { + assert.Error(t, err) + assert.Equal(t, tc.expectedError, err.Error()) + assert.Equal(t, tc.expectedResult, result) + } + }) + } +} From dac3b5031ecc3ca7653f6eaaffdabd4e65ad08ad Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Fri, 10 Nov 2023 09:55:20 -0300 Subject: [PATCH 08/19] feat: craeting the GetMe method with struct types --- server/client_server.go | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/server/client_server.go b/server/client_server.go index c9a5ea9..a0fdafe 100644 --- a/server/client_server.go +++ b/server/client_server.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/json" "fmt" "io" "net/http" @@ -11,6 +12,19 @@ import ( "golang.org/x/oauth2" ) +// TODO: This will be changed to create the main structs when modularized +type Link struct { + Href string `json:"href"` +} + +type BitbucketUser struct { + AccountId int `json:"id"` + Username string `json:"name"` + Links struct { + Self []Link `json:"self"` + } `json:"links"` +} + type BitbucketServerClient struct { apiClient *bitbucketv1.APIClient @@ -73,6 +87,27 @@ func (c *BitbucketServerClient) getWhoAmI() (string, error) { return string(user), nil } -func (c *BitbucketServerClient) GetMe() (string, error) { - return c.getWhoAmI() +func (c *BitbucketServerClient) GetMe() (*BitbucketUser, error) { + username, err := c.getWhoAmI() + if err != nil { + return nil, err + } + + resp, err := c.apiClient.DefaultApi.GetUser(username) + if err != nil { + return nil, err + } + + jsonData, err := json.Marshal(resp.Values) + if err != nil { + return nil, err + } + + var user BitbucketUser + err = json.Unmarshal(jsonData, &user) + if err != nil { + return nil, err + } + + return &user, nil } From 92655b06359cb8a4e4ce54f72554a1e2abf6f4b8 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 28 Nov 2023 20:59:48 -0300 Subject: [PATCH 09/19] feat: creating the bitbucket_server package --- .../{ => bitbucket_server}/client_server.go | 10 +- server/bitbucket_server/client_server_test.go | 131 ++++++++++++++++++ server/client_server_test.go | 63 --------- server/plugin.go | 5 +- 4 files changed, 139 insertions(+), 70 deletions(-) rename server/{ => bitbucket_server}/client_server.go (87%) create mode 100644 server/bitbucket_server/client_server_test.go delete mode 100644 server/client_server_test.go diff --git a/server/client_server.go b/server/bitbucket_server/client_server.go similarity index 87% rename from server/client_server.go rename to server/bitbucket_server/client_server.go index a0fdafe..38d9736 100644 --- a/server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -1,4 +1,4 @@ -package main +package bitbucket_server import ( "context" @@ -39,19 +39,19 @@ func NewClientServer() *BitbucketServerClient { } // TODO: This method needs to be changed when Modularization is built -func (c *BitbucketServerClient) Connect(config Configuration, token oauth2.Token, ts oauth2.TokenSource) *BitbucketServerClient { +func (c *BitbucketServerClient) Connect(selfHostedURL string, apiSelfHostedURL string, token oauth2.Token, ts oauth2.TokenSource) *BitbucketServerClient { // setup Oauth context auth := context.WithValue(context.Background(), bitbucketv1.ContextOAuth2, ts) tc := oauth2.NewClient(auth, ts) // create config for bitbucket API - configBb := bitbucketv1.NewConfiguration(config.BitbucketAPISelfHostedURL) + configBb := bitbucketv1.NewConfiguration(apiSelfHostedURL) configBb.HTTPClient = tc c.apiClient = bitbucketv1.NewAPIClient(context.Background(), configBb) - c.selfHostedURL = config.BitbucketSelfHostedURL - c.selfHostedAPIURL = config.BitbucketAPISelfHostedURL + c.selfHostedURL = selfHostedURL + c.selfHostedAPIURL = apiSelfHostedURL c.token = token return c diff --git a/server/bitbucket_server/client_server_test.go b/server/bitbucket_server/client_server_test.go new file mode 100644 index 0000000..618f381 --- /dev/null +++ b/server/bitbucket_server/client_server_test.go @@ -0,0 +1,131 @@ +package bitbucket_server + +import ( + "bytes" + "io" + "net/http" + "net/http/httptest" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "golang.org/x/oauth2" +) + +type MockAPIClient struct { + mock.Mock +} + +func (m *MockAPIClient) GetUser(username string) (*http.Response, error) { + args := m.Called(username) + mockResp := mockHTTPResponse(200, `{"id": 1, "name": "John Doe", "links": {"self": [{"href": "http://example.com"}]}}`) + return mockResp, args.Error(1) +} + +func mockHTTPResponse(statusCode int, responseBody string) *http.Response { + return &http.Response{ + StatusCode: statusCode, + Body: io.NopCloser(bytes.NewBufferString(responseBody)), + } +} + +func TestGetWhoAmI(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + authHeader := r.Header.Get("Authorization") + if authHeader != "Bearer valid-token" { + w.WriteHeader(http.StatusUnauthorized) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("mocked-user")) + })) + defer server.Close() + + tests := []struct { + name string + token oauth2.Token + expectedResult string + expectedError string + }{ + { + name: "valid token", + token: oauth2.Token{AccessToken: "valid-token"}, + expectedResult: "mocked-user", + expectedError: "", + }, + { + name: "invalid token", + token: oauth2.Token{AccessToken: "invalid-token"}, + expectedResult: "", + expectedError: "who am i returned non-200 status code: 401", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + client := NewClientServer() + client.selfHostedURL = server.URL + client.token = tc.token + + result, err := client.getWhoAmI() + + if tc.expectedError == "" { + assert.NoError(t, err) + assert.Equal(t, tc.expectedResult, result) + } else { + assert.Error(t, err) + assert.Equal(t, tc.expectedError, err.Error()) + assert.Equal(t, tc.expectedResult, result) + } + }) + } +} + +func TestBitbucketServerClient_GetMe(t *testing.T) { + tests := []struct { + name string + setupMock func(*MockAPIClient) + expectedUser *BitbucketUser + expectedErr error + }{ + { + name: "successful retrieval", + setupMock: func(m *MockAPIClient) { + m.On("GetUser", mock.Anything).Return(mockHTTPResponse(200, `{"id": 1, "name": "John Doe", "links": {"self": [{"href": "http://example.com"}]}}`), nil) + }, + expectedUser: &BitbucketUser{ /* expected data */ }, + expectedErr: nil, + }, + { + name: "getWhoAmI fails", + setupMock: func(m *MockAPIClient) {}, + expectedUser: nil, + expectedErr: errors.New("getWhoAmI error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAPIClient := &MockAPIClient{} + tt.setupMock(mockAPIClient) + + c := &BitbucketServerClient{ + apiClient: mockAPIClient, + } + + user, err := c.GetMe() + + assert.Equal(t, tt.expectedUser, user) + if tt.expectedErr != nil { + assert.Error(t, err) + assert.EqualError(t, err, tt.expectedErr.Error()) + } else { + assert.NoError(t, err) + } + + mockAPIClient.AssertExpectations(t) + }) + } +} diff --git a/server/client_server_test.go b/server/client_server_test.go deleted file mode 100644 index 57afd30..0000000 --- a/server/client_server_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/assert" - "golang.org/x/oauth2" -) - -func TestGetWhoAmI(t *testing.T) { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - authHeader := r.Header.Get("Authorization") - if authHeader != "Bearer valid-token" { - w.WriteHeader(http.StatusUnauthorized) - return - } - - w.WriteHeader(http.StatusOK) - w.Write([]byte("mocked-user")) - })) - defer server.Close() - - tests := []struct { - name string - token oauth2.Token - expectedResult string - expectedError string - }{ - { - name: "valid token", - token: oauth2.Token{AccessToken: "valid-token"}, - expectedResult: "mocked-user", - expectedError: "", - }, - { - name: "invalid token", - token: oauth2.Token{AccessToken: "invalid-token"}, - expectedResult: "", - expectedError: "who am i returned non-200 status code: 401", - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - client := NewClientServer() - client.selfHostedURL = server.URL - client.token = tc.token - - result, err := client.getWhoAmI() - - if tc.expectedError == "" { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) - } else { - assert.Error(t, err) - assert.Equal(t, tc.expectedError, err.Error()) - assert.Equal(t, tc.expectedResult, result) - } - }) - } -} diff --git a/server/plugin.go b/server/plugin.go index 678fa97..a7806d6 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -21,6 +21,7 @@ import ( "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/plugin" + "github.com/mattermost/mattermost-plugin-bitbucket/server/bitbucket_server" "github.com/mattermost/mattermost-plugin-bitbucket/server/templaterenderer" "github.com/mattermost/mattermost-plugin-bitbucket/server/webhook" ) @@ -64,7 +65,7 @@ type Plugin struct { router *mux.Router // TODO: This can be converted into a generic client - bitbucketClient *BitbucketServerClient + bitbucketClient *bitbucket_server.BitbucketServerClient } // NewPlugin returns an instance of a Plugin. @@ -82,7 +83,7 @@ func NewPlugin() *Plugin { } // TODO: This can be converted into a generic client - p.bitbucketClient = NewClientServer() + p.bitbucketClient = bitbucket_server.NewClientServer() return p } From 0110aa0074064be7defffd931b7b19b6df641f2d Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 28 Nov 2023 21:02:00 -0300 Subject: [PATCH 10/19] feat: fix linting rules --- server/bitbucket_server/client_server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/bitbucket_server/client_server.go b/server/bitbucket_server/client_server.go index 38d9736..eee5d8d 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -18,7 +18,7 @@ type Link struct { } type BitbucketUser struct { - AccountId int `json:"id"` + AccountID int `json:"id"` Username string `json:"name"` Links struct { Self []Link `json:"self"` @@ -58,9 +58,9 @@ func (c *BitbucketServerClient) Connect(selfHostedURL string, apiSelfHostedURL s } func (c *BitbucketServerClient) getWhoAmI() (string, error) { - baseUrl := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.selfHostedURL) + requestURL := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.selfHostedURL) - req, err := http.NewRequest("GET", baseUrl, nil) + req, err := http.NewRequest("GET", requestURL, nil) if err != nil { return "", err } From 6028704067092c7aae3b341eb03aebef43c83f78 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Mon, 4 Dec 2023 21:22:32 -0300 Subject: [PATCH 11/19] feat: adding a bitbucket client factory --- server/bitbucket_server/client.go | 19 +++++++++++++ server/bitbucket_server/client_server.go | 36 +++++------------------- server/bitbucket_server/factory.go | 14 +++++++++ server/plugin.go | 33 ++++++++++++++++++---- 4 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 server/bitbucket_server/client.go create mode 100644 server/bitbucket_server/factory.go diff --git a/server/bitbucket_server/client.go b/server/bitbucket_server/client.go new file mode 100644 index 0000000..e698d3a --- /dev/null +++ b/server/bitbucket_server/client.go @@ -0,0 +1,19 @@ +package bitbucket_server + +import ( + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" + "golang.org/x/oauth2" +) + +type Client interface { + GetMe() (*BitbucketUser, error) +} + +type BitbucketClient struct { + apiClient *bitbucketv1.APIClient + + selfHostedURL string + selfHostedAPIURL string + + token oauth2.Token +} diff --git a/server/bitbucket_server/client_server.go b/server/bitbucket_server/client_server.go index eee5d8d..7d6ad47 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -1,7 +1,6 @@ package bitbucket_server import ( - "context" "encoding/json" "fmt" "io" @@ -9,7 +8,6 @@ import ( bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/pkg/errors" - "golang.org/x/oauth2" ) // TODO: This will be changed to create the main structs when modularized @@ -26,35 +24,15 @@ type BitbucketUser struct { } type BitbucketServerClient struct { - apiClient *bitbucketv1.APIClient - - selfHostedURL string - selfHostedAPIURL string - - token oauth2.Token + BitbucketClient } -func NewClientServer() *BitbucketServerClient { - return &BitbucketServerClient{} -} - -// TODO: This method needs to be changed when Modularization is built -func (c *BitbucketServerClient) Connect(selfHostedURL string, apiSelfHostedURL string, token oauth2.Token, ts oauth2.TokenSource) *BitbucketServerClient { - // setup Oauth context - auth := context.WithValue(context.Background(), bitbucketv1.ContextOAuth2, ts) - - tc := oauth2.NewClient(auth, ts) - - // create config for bitbucket API - configBb := bitbucketv1.NewConfiguration(apiSelfHostedURL) - configBb.HTTPClient = tc - - c.apiClient = bitbucketv1.NewAPIClient(context.Background(), configBb) - c.selfHostedURL = selfHostedURL - c.selfHostedAPIURL = apiSelfHostedURL - c.token = token - - return c +func newServerClient(apiClient *bitbucketv1.APIClient) Client { + return &BitbucketServerClient{ + BitbucketClient: BitbucketClient{ + apiClient: apiClient, + }, + } } func (c *BitbucketServerClient) getWhoAmI() (string, error) { diff --git a/server/bitbucket_server/factory.go b/server/bitbucket_server/factory.go new file mode 100644 index 0000000..5035a6f --- /dev/null +++ b/server/bitbucket_server/factory.go @@ -0,0 +1,14 @@ +package bitbucket_server + +import ( + "fmt" + + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" +) + +func GetBitbucketClient(clientType string, apiClient *bitbucketv1.APIClient) (Client, error) { + if clientType == "server" { + return newServerClient(apiClient), nil + } + return nil, fmt.Errorf("wrong client passed") +} diff --git a/server/plugin.go b/server/plugin.go index a7806d6..c3acb21 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -12,6 +12,7 @@ import ( "strings" "sync" + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/wbrefvem/go-bitbucket" @@ -63,9 +64,6 @@ type Plugin struct { webhookHandler webhook.Webhook router *mux.Router - - // TODO: This can be converted into a generic client - bitbucketClient *bitbucket_server.BitbucketServerClient } // NewPlugin returns an instance of a Plugin. @@ -82,9 +80,6 @@ func NewPlugin() *Plugin { "settings": p.handleSettings, } - // TODO: This can be converted into a generic client - p.bitbucketClient = bitbucket_server.NewClientServer() - return p } @@ -112,6 +107,32 @@ func (p *Plugin) bitbucketConnect(token oauth2.Token) *bitbucket.APIClient { return bitbucket.NewAPIClient(configBb) } +func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Client { + // get Oauth token source and client + ts := p.getOAuthConfig().TokenSource(context.Background(), &token) + + // setup Oauth context + auth := context.WithValue(context.Background(), bitbucket.ContextOAuth2, ts) + + tc := oauth2.NewClient(auth, ts) + + apiSelfHostedURL := p.configuration.BitbucketAPISelfHostedURL + + // create config for bitbucket API + configBb := bitbucketv1.NewConfiguration(apiSelfHostedURL) + configBb.HTTPClient = tc + + apiClient := bitbucketv1.NewAPIClient(context.Background(), configBb) + + bitbucketServer, err := bitbucket_server.GetBitbucketClient("server", apiClient) + if err != nil { + p.API.LogError("Error while connecting to bitbucket server", "err", err.Error()) + return nil + } + + return bitbucketServer +} + func (p *Plugin) OnActivate() error { config := p.getConfiguration() From 477c06e9b8ebbcc0a7ce024febc335d703e09d50 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Mon, 4 Dec 2023 21:31:39 -0300 Subject: [PATCH 12/19] feat: adjustments to the access token --- server/bitbucket_server/client.go | 9 ++------- server/bitbucket_server/client_server.go | 14 ++++++++------ server/bitbucket_server/factory.go | 4 ++-- server/plugin.go | 3 ++- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/server/bitbucket_server/client.go b/server/bitbucket_server/client.go index e698d3a..5f2507a 100644 --- a/server/bitbucket_server/client.go +++ b/server/bitbucket_server/client.go @@ -1,12 +1,9 @@ package bitbucket_server -import ( - bitbucketv1 "github.com/gfleury/go-bitbucket-v1" - "golang.org/x/oauth2" -) +import bitbucketv1 "github.com/gfleury/go-bitbucket-v1" type Client interface { - GetMe() (*BitbucketUser, error) + GetMe(accessToken string) (*BitbucketUser, error) } type BitbucketClient struct { @@ -14,6 +11,4 @@ type BitbucketClient struct { selfHostedURL string selfHostedAPIURL string - - token oauth2.Token } diff --git a/server/bitbucket_server/client_server.go b/server/bitbucket_server/client_server.go index 7d6ad47..94d069a 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -27,15 +27,17 @@ type BitbucketServerClient struct { BitbucketClient } -func newServerClient(apiClient *bitbucketv1.APIClient) Client { +func newServerClient(selfHostedURL string, selfHostedAPIURL string, apiClient *bitbucketv1.APIClient) Client { return &BitbucketServerClient{ BitbucketClient: BitbucketClient{ - apiClient: apiClient, + apiClient: apiClient, + selfHostedURL: selfHostedURL, + selfHostedAPIURL: selfHostedAPIURL, }, } } -func (c *BitbucketServerClient) getWhoAmI() (string, error) { +func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { requestURL := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.selfHostedURL) req, err := http.NewRequest("GET", requestURL, nil) @@ -45,7 +47,7 @@ func (c *BitbucketServerClient) getWhoAmI() (string, error) { client := &http.Client{} - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.token.AccessToken)) + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken)) resp, err := client.Do(req) if err != nil { @@ -65,8 +67,8 @@ func (c *BitbucketServerClient) getWhoAmI() (string, error) { return string(user), nil } -func (c *BitbucketServerClient) GetMe() (*BitbucketUser, error) { - username, err := c.getWhoAmI() +func (c *BitbucketServerClient) GetMe(accessToken string) (*BitbucketUser, error) { + username, err := c.getWhoAmI(accessToken) if err != nil { return nil, err } diff --git a/server/bitbucket_server/factory.go b/server/bitbucket_server/factory.go index 5035a6f..e04d9c3 100644 --- a/server/bitbucket_server/factory.go +++ b/server/bitbucket_server/factory.go @@ -6,9 +6,9 @@ import ( bitbucketv1 "github.com/gfleury/go-bitbucket-v1" ) -func GetBitbucketClient(clientType string, apiClient *bitbucketv1.APIClient) (Client, error) { +func GetBitbucketClient(clientType string, selfHostedURL string, selfHostedAPIURL string, apiClient *bitbucketv1.APIClient) (Client, error) { if clientType == "server" { - return newServerClient(apiClient), nil + return newServerClient(selfHostedURL, selfHostedAPIURL, apiClient), nil } return nil, fmt.Errorf("wrong client passed") } diff --git a/server/plugin.go b/server/plugin.go index c3acb21..5d7961d 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -116,6 +116,7 @@ func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Cli tc := oauth2.NewClient(auth, ts) + selfHostedURL := p.configuration.BitbucketSelfHostedURL apiSelfHostedURL := p.configuration.BitbucketAPISelfHostedURL // create config for bitbucket API @@ -124,7 +125,7 @@ func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Cli apiClient := bitbucketv1.NewAPIClient(context.Background(), configBb) - bitbucketServer, err := bitbucket_server.GetBitbucketClient("server", apiClient) + bitbucketServer, err := bitbucket_server.GetBitbucketClient("server", selfHostedURL, apiSelfHostedURL, apiClient) if err != nil { p.API.LogError("Error while connecting to bitbucket server", "err", err.Error()) return nil From 7abb29977fd48e6c9a386244bf6829fbfe88051b Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Wed, 6 Dec 2023 11:25:33 -0300 Subject: [PATCH 13/19] feat: adding the logger as a configuration --- server/bitbucket_server/client.go | 7 +----- server/bitbucket_server/client_server.go | 30 +++++++++++++++++------- server/bitbucket_server/factory.go | 12 ++++++++-- server/plugin.go | 9 ++++++- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/server/bitbucket_server/client.go b/server/bitbucket_server/client.go index 5f2507a..84a5ee0 100644 --- a/server/bitbucket_server/client.go +++ b/server/bitbucket_server/client.go @@ -1,14 +1,9 @@ package bitbucket_server -import bitbucketv1 "github.com/gfleury/go-bitbucket-v1" - type Client interface { GetMe(accessToken string) (*BitbucketUser, error) } type BitbucketClient struct { - apiClient *bitbucketv1.APIClient - - selfHostedURL string - selfHostedAPIURL string + ClientConfiguration } diff --git a/server/bitbucket_server/client_server.go b/server/bitbucket_server/client_server.go index 94d069a..85a4947 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -6,7 +6,6 @@ import ( "io" "net/http" - bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/pkg/errors" ) @@ -27,21 +26,25 @@ type BitbucketServerClient struct { BitbucketClient } -func newServerClient(selfHostedURL string, selfHostedAPIURL string, apiClient *bitbucketv1.APIClient) Client { +func newServerClient(config ClientConfiguration) Client { return &BitbucketServerClient{ BitbucketClient: BitbucketClient{ - apiClient: apiClient, - selfHostedURL: selfHostedURL, - selfHostedAPIURL: selfHostedAPIURL, + ClientConfiguration: ClientConfiguration{ + SelfHostedURL: config.SelfHostedURL, + SelfHostedAPIURL: config.SelfHostedAPIURL, + APIClient: config.APIClient, + LogError: config.LogError, + }, }, } } func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { - requestURL := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.selfHostedURL) + requestURL := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.SelfHostedURL) req, err := http.NewRequest("GET", requestURL, nil) if err != nil { + c.LogError("unable to create request for getting whoami identity", "error", err.Error()) return "", err } @@ -51,17 +54,22 @@ func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { resp, err := client.Do(req) if err != nil { + c.LogError("failed to make the request for getting whoami identity", "error", err.Error()) return "", err } defer resp.Body.Close() if resp.StatusCode != 200 { - return "", errors.Errorf("who am i returned non-200 status code: %d", resp.StatusCode) + errMessage := fmt.Sprintf("who am i returned non-200 status code: %d", resp.StatusCode) + err := errors.Errorf(errMessage) + c.LogError(errMessage, "error", err.Error()) + return "", err } user, err := io.ReadAll(resp.Body) if err != nil { - return "", errors.Wrap(err, "failed to read response") + c.LogError("failed to make the request for getting whoami identity", "error", err.Error()) + return "", err } return string(user), nil @@ -70,22 +78,26 @@ func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { func (c *BitbucketServerClient) GetMe(accessToken string) (*BitbucketUser, error) { username, err := c.getWhoAmI(accessToken) if err != nil { + c.LogError("failed to get whoami identity", "error", err.Error()) return nil, err } - resp, err := c.apiClient.DefaultApi.GetUser(username) + resp, err := c.APIClient.DefaultApi.GetUser(username) if err != nil { + c.LogError("failed to get user from bitbucket server", "error", err.Error()) return nil, err } jsonData, err := json.Marshal(resp.Values) if err != nil { + c.LogError("failed to marshaling user from bitbucket server", "error", err.Error()) return nil, err } var user BitbucketUser err = json.Unmarshal(jsonData, &user) if err != nil { + c.LogError("failed to parse user from bitbucket server", "error", err.Error()) return nil, err } diff --git a/server/bitbucket_server/factory.go b/server/bitbucket_server/factory.go index e04d9c3..b929265 100644 --- a/server/bitbucket_server/factory.go +++ b/server/bitbucket_server/factory.go @@ -6,9 +6,17 @@ import ( bitbucketv1 "github.com/gfleury/go-bitbucket-v1" ) -func GetBitbucketClient(clientType string, selfHostedURL string, selfHostedAPIURL string, apiClient *bitbucketv1.APIClient) (Client, error) { +type ClientConfiguration struct { + SelfHostedURL string + SelfHostedAPIURL string + APIClient *bitbucketv1.APIClient + + LogError func(msg string, keyValuePairs ...interface{}) +} + +func GetBitbucketClient(clientType string, config ClientConfiguration) (Client, error) { if clientType == "server" { - return newServerClient(selfHostedURL, selfHostedAPIURL, apiClient), nil + return newServerClient(config), nil } return nil, fmt.Errorf("wrong client passed") } diff --git a/server/plugin.go b/server/plugin.go index 5d7961d..53f3d6a 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -125,7 +125,14 @@ func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Cli apiClient := bitbucketv1.NewAPIClient(context.Background(), configBb) - bitbucketServer, err := bitbucket_server.GetBitbucketClient("server", selfHostedURL, apiSelfHostedURL, apiClient) + configClient := bitbucket_server.ClientConfiguration{ + SelfHostedURL: selfHostedURL, + SelfHostedAPIURL: apiSelfHostedURL, + APIClient: apiClient, + LogError: p.API.LogError, + } + + bitbucketServer, err := bitbucket_server.GetBitbucketClient("server", configClient) if err != nil { p.API.LogError("Error while connecting to bitbucket server", "err", err.Error()) return nil From 1682d75407b2583458b57c5ebc890e2fa243a1ff Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Wed, 6 Dec 2023 11:34:39 -0300 Subject: [PATCH 14/19] feat: wrapping errors in a custom message to have more tracking --- server/bitbucket_server/client_server.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/server/bitbucket_server/client_server.go b/server/bitbucket_server/client_server.go index 85a4947..65b5605 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -44,8 +44,7 @@ func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { req, err := http.NewRequest("GET", requestURL, nil) if err != nil { - c.LogError("unable to create request for getting whoami identity", "error", err.Error()) - return "", err + return "", errors.Wrap(err, "unable to create request for getting whoami identity") } client := &http.Client{} @@ -54,22 +53,18 @@ func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { resp, err := client.Do(req) if err != nil { - c.LogError("failed to make the request for getting whoami identity", "error", err.Error()) - return "", err + return "", errors.Wrap(err, "failed to make the request for getting whoami identity") } defer resp.Body.Close() if resp.StatusCode != 200 { - errMessage := fmt.Sprintf("who am i returned non-200 status code: %d", resp.StatusCode) - err := errors.Errorf(errMessage) - c.LogError(errMessage, "error", err.Error()) + err := errors.Errorf("who am i returned non-200 status code: %d", resp.StatusCode) return "", err } user, err := io.ReadAll(resp.Body) if err != nil { - c.LogError("failed to make the request for getting whoami identity", "error", err.Error()) - return "", err + return "", errors.Wrap(err, "failed to make the request for getting whoami identity") } return string(user), nil From c2c210c734a7e89ffd4ecb27249b11a7f4ef3cf5 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Tue, 9 Jan 2024 12:19:20 -0300 Subject: [PATCH 15/19] feat: using the oauth2.Client to make the requests inside the bitbucket server --- server/bitbucket_server/client.go | 2 +- server/bitbucket_server/client_server.go | 13 +++++-------- server/bitbucket_server/factory.go | 2 ++ server/plugin.go | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server/bitbucket_server/client.go b/server/bitbucket_server/client.go index 84a5ee0..690d4d1 100644 --- a/server/bitbucket_server/client.go +++ b/server/bitbucket_server/client.go @@ -1,7 +1,7 @@ package bitbucket_server type Client interface { - GetMe(accessToken string) (*BitbucketUser, error) + GetMe() (*BitbucketUser, error) } type BitbucketClient struct { diff --git a/server/bitbucket_server/client_server.go b/server/bitbucket_server/client_server.go index 65b5605..aed7da6 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucket_server/client_server.go @@ -33,13 +33,14 @@ func newServerClient(config ClientConfiguration) Client { SelfHostedURL: config.SelfHostedURL, SelfHostedAPIURL: config.SelfHostedAPIURL, APIClient: config.APIClient, + OAuthClient: config.OAuthClient, LogError: config.LogError, }, }, } } -func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { +func (c *BitbucketServerClient) getWhoAmI() (string, error) { requestURL := fmt.Sprintf("%s/plugins/servlet/applinks/whoami", c.SelfHostedURL) req, err := http.NewRequest("GET", requestURL, nil) @@ -47,11 +48,7 @@ func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { return "", errors.Wrap(err, "unable to create request for getting whoami identity") } - client := &http.Client{} - - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken)) - - resp, err := client.Do(req) + resp, err := c.OAuthClient.Do(req) if err != nil { return "", errors.Wrap(err, "failed to make the request for getting whoami identity") } @@ -70,8 +67,8 @@ func (c *BitbucketServerClient) getWhoAmI(accessToken string) (string, error) { return string(user), nil } -func (c *BitbucketServerClient) GetMe(accessToken string) (*BitbucketUser, error) { - username, err := c.getWhoAmI(accessToken) +func (c *BitbucketServerClient) GetMe() (*BitbucketUser, error) { + username, err := c.getWhoAmI() if err != nil { c.LogError("failed to get whoami identity", "error", err.Error()) return nil, err diff --git a/server/bitbucket_server/factory.go b/server/bitbucket_server/factory.go index b929265..d0978f6 100644 --- a/server/bitbucket_server/factory.go +++ b/server/bitbucket_server/factory.go @@ -2,6 +2,7 @@ package bitbucket_server import ( "fmt" + "net/http" bitbucketv1 "github.com/gfleury/go-bitbucket-v1" ) @@ -10,6 +11,7 @@ type ClientConfiguration struct { SelfHostedURL string SelfHostedAPIURL string APIClient *bitbucketv1.APIClient + OAuthClient *http.Client LogError func(msg string, keyValuePairs ...interface{}) } diff --git a/server/plugin.go b/server/plugin.go index 53f3d6a..857157d 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -129,6 +129,7 @@ func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Cli SelfHostedURL: selfHostedURL, SelfHostedAPIURL: apiSelfHostedURL, APIClient: apiClient, + OAuthClient: tc, LogError: p.API.LogError, } From 04549b36069a0616e6a68bc925b0c7b341a0a6b0 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Thu, 11 Jan 2024 19:13:05 -0300 Subject: [PATCH 16/19] tests the getWhoAmI --- server/bitbucket_server/client_server_test.go | 133 +++--------------- 1 file changed, 20 insertions(+), 113 deletions(-) diff --git a/server/bitbucket_server/client_server_test.go b/server/bitbucket_server/client_server_test.go index 618f381..43ecb39 100644 --- a/server/bitbucket_server/client_server_test.go +++ b/server/bitbucket_server/client_server_test.go @@ -1,131 +1,38 @@ package bitbucket_server import ( - "bytes" - "io" "net/http" "net/http/httptest" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "golang.org/x/oauth2" ) -type MockAPIClient struct { - mock.Mock -} - -func (m *MockAPIClient) GetUser(username string) (*http.Response, error) { - args := m.Called(username) - mockResp := mockHTTPResponse(200, `{"id": 1, "name": "John Doe", "links": {"self": [{"href": "http://example.com"}]}}`) - return mockResp, args.Error(1) -} - -func mockHTTPResponse(statusCode int, responseBody string) *http.Response { - return &http.Response{ - StatusCode: statusCode, - Body: io.NopCloser(bytes.NewBufferString(responseBody)), - } -} - func TestGetWhoAmI(t *testing.T) { - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - authHeader := r.Header.Get("Authorization") - if authHeader != "Bearer valid-token" { - w.WriteHeader(http.StatusUnauthorized) - return - } - - w.WriteHeader(http.StatusOK) - w.Write([]byte("mocked-user")) - })) - defer server.Close() - - tests := []struct { - name string - token oauth2.Token - expectedResult string - expectedError string - }{ - { - name: "valid token", - token: oauth2.Token{AccessToken: "valid-token"}, - expectedResult: "mocked-user", - expectedError: "", - }, - { - name: "invalid token", - token: oauth2.Token{AccessToken: "invalid-token"}, - expectedResult: "", - expectedError: "who am i returned non-200 status code: 401", - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - client := NewClientServer() - client.selfHostedURL = server.URL - client.token = tc.token - - result, err := client.getWhoAmI() - - if tc.expectedError == "" { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) - } else { - assert.Error(t, err) - assert.Equal(t, tc.expectedError, err.Error()) - assert.Equal(t, tc.expectedResult, result) - } - }) - } -} + t.Run("successfuly get who am i from oauth", func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("testuser")) + })) + defer ts.Close() -func TestBitbucketServerClient_GetMe(t *testing.T) { - tests := []struct { - name string - setupMock func(*MockAPIClient) - expectedUser *BitbucketUser - expectedErr error - }{ - { - name: "successful retrieval", - setupMock: func(m *MockAPIClient) { - m.On("GetUser", mock.Anything).Return(mockHTTPResponse(200, `{"id": 1, "name": "John Doe", "links": {"self": [{"href": "http://example.com"}]}}`), nil) - }, - expectedUser: &BitbucketUser{ /* expected data */ }, - expectedErr: nil, - }, - { - name: "getWhoAmI fails", - setupMock: func(m *MockAPIClient) {}, - expectedUser: nil, - expectedErr: errors.New("getWhoAmI error"), - }, - } + client := newServerClient(ClientConfiguration{SelfHostedURL: ts.URL, OAuthClient: ts.Client()}).(*BitbucketServerClient) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - mockAPIClient := &MockAPIClient{} - tt.setupMock(mockAPIClient) + username, err := client.getWhoAmI() - c := &BitbucketServerClient{ - apiClient: mockAPIClient, - } + assert.Nil(t, err) + assert.Equal(t, "testuser", username) + }) - user, err := c.GetMe() + t.Run("return error when the status code is different than 200", func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + })) + defer ts.Close() - assert.Equal(t, tt.expectedUser, user) - if tt.expectedErr != nil { - assert.Error(t, err) - assert.EqualError(t, err, tt.expectedErr.Error()) - } else { - assert.NoError(t, err) - } + client := newServerClient(ClientConfiguration{SelfHostedURL: ts.URL, OAuthClient: ts.Client()}).(*BitbucketServerClient) - mockAPIClient.AssertExpectations(t) - }) - } + _, err := client.getWhoAmI() + assert.Error(t, err) + }) } From e39375307452b7ac14da84503c729fe069d6ee34 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Wed, 17 Jan 2024 23:06:26 -0300 Subject: [PATCH 17/19] feat: lint and renaming things --- .../client.go | 2 +- .../client_server.go | 2 +- .../client_server_test.go | 15 +++++++++++++-- .../factory.go | 2 +- server/plugin.go | 8 ++++---- 5 files changed, 20 insertions(+), 9 deletions(-) rename server/{bitbucket_server => bitbucketclient}/client.go (82%) rename server/{bitbucket_server => bitbucketclient}/client_server.go (98%) rename server/{bitbucket_server => bitbucketclient}/client_server_test.go (71%) rename server/{bitbucket_server => bitbucketclient}/factory.go (95%) diff --git a/server/bitbucket_server/client.go b/server/bitbucketclient/client.go similarity index 82% rename from server/bitbucket_server/client.go rename to server/bitbucketclient/client.go index 690d4d1..f420322 100644 --- a/server/bitbucket_server/client.go +++ b/server/bitbucketclient/client.go @@ -1,4 +1,4 @@ -package bitbucket_server +package bitbucketclient type Client interface { GetMe() (*BitbucketUser, error) diff --git a/server/bitbucket_server/client_server.go b/server/bitbucketclient/client_server.go similarity index 98% rename from server/bitbucket_server/client_server.go rename to server/bitbucketclient/client_server.go index aed7da6..6cad993 100644 --- a/server/bitbucket_server/client_server.go +++ b/server/bitbucketclient/client_server.go @@ -1,4 +1,4 @@ -package bitbucket_server +package bitbucketclient import ( "encoding/json" diff --git a/server/bitbucket_server/client_server_test.go b/server/bitbucketclient/client_server_test.go similarity index 71% rename from server/bitbucket_server/client_server_test.go rename to server/bitbucketclient/client_server_test.go index 43ecb39..cca44e8 100644 --- a/server/bitbucket_server/client_server_test.go +++ b/server/bitbucketclient/client_server_test.go @@ -1,15 +1,26 @@ -package bitbucket_server +package bitbucketclient import ( "net/http" "net/http/httptest" "testing" + bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) +type MockAPIClient struct { + mock.Mock +} + +func (m *MockAPIClient) GetUser(_ string) (*bitbucketv1.APIResponse, error) { + args := m.Called() + return args.Get(0).(*bitbucketv1.APIResponse), args.Error(1) +} + func TestGetWhoAmI(t *testing.T) { - t.Run("successfuly get who am i from oauth", func(t *testing.T) { + t.Run("successfully get who am i from oauth", func(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("testuser")) diff --git a/server/bitbucket_server/factory.go b/server/bitbucketclient/factory.go similarity index 95% rename from server/bitbucket_server/factory.go rename to server/bitbucketclient/factory.go index d0978f6..336da5d 100644 --- a/server/bitbucket_server/factory.go +++ b/server/bitbucketclient/factory.go @@ -1,4 +1,4 @@ -package bitbucket_server +package bitbucketclient import ( "fmt" diff --git a/server/plugin.go b/server/plugin.go index 857157d..f072327 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -22,7 +22,7 @@ import ( "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/plugin" - "github.com/mattermost/mattermost-plugin-bitbucket/server/bitbucket_server" + "github.com/mattermost/mattermost-plugin-bitbucket/server/bitbucketclient" "github.com/mattermost/mattermost-plugin-bitbucket/server/templaterenderer" "github.com/mattermost/mattermost-plugin-bitbucket/server/webhook" ) @@ -107,7 +107,7 @@ func (p *Plugin) bitbucketConnect(token oauth2.Token) *bitbucket.APIClient { return bitbucket.NewAPIClient(configBb) } -func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Client { +func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucketclient.Client { // get Oauth token source and client ts := p.getOAuthConfig().TokenSource(context.Background(), &token) @@ -125,7 +125,7 @@ func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Cli apiClient := bitbucketv1.NewAPIClient(context.Background(), configBb) - configClient := bitbucket_server.ClientConfiguration{ + configClient := bitbucketclient.ClientConfiguration{ SelfHostedURL: selfHostedURL, SelfHostedAPIURL: apiSelfHostedURL, APIClient: apiClient, @@ -133,7 +133,7 @@ func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucket_server.Cli LogError: p.API.LogError, } - bitbucketServer, err := bitbucket_server.GetBitbucketClient("server", configClient) + bitbucketServer, err := bitbucketclient.GetBitbucketClient("server", configClient) if err != nil { p.API.LogError("Error while connecting to bitbucket server", "err", err.Error()) return nil From d790e0a320e3ecbb50c8820e13ee6894113e4beb Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Wed, 17 Jan 2024 23:11:36 -0300 Subject: [PATCH 18/19] fix more lint problems --- server/bitbucketclient/client_server.go | 3 +-- server/bitbucketclient/client_server_test.go | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/bitbucketclient/client_server.go b/server/bitbucketclient/client_server.go index 6cad993..5411502 100644 --- a/server/bitbucketclient/client_server.go +++ b/server/bitbucketclient/client_server.go @@ -55,8 +55,7 @@ func (c *BitbucketServerClient) getWhoAmI() (string, error) { defer resp.Body.Close() if resp.StatusCode != 200 { - err := errors.Errorf("who am i returned non-200 status code: %d", resp.StatusCode) - return "", err + return "", errors.Errorf("who am i returned non-200 status code: %d", resp.StatusCode) } user, err := io.ReadAll(resp.Body) diff --git a/server/bitbucketclient/client_server_test.go b/server/bitbucketclient/client_server_test.go index cca44e8..75b188a 100644 --- a/server/bitbucketclient/client_server_test.go +++ b/server/bitbucketclient/client_server_test.go @@ -23,7 +23,10 @@ func TestGetWhoAmI(t *testing.T) { t.Run("successfully get who am i from oauth", func(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) - w.Write([]byte("testuser")) + _, err := w.Write([]byte("testuser")) + if err != nil { + t.Fatalf("Failed to write response: %v", err) + } })) defer ts.Close() From d7fd5d90ec7a7a37227580dc99e0acadca548809 Mon Sep 17 00:00:00 2001 From: panoramix360 Date: Wed, 24 Jan 2024 15:47:45 -0300 Subject: [PATCH 19/19] feat: removing the bitbucket server connect for now --- server/plugin.go | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/server/plugin.go b/server/plugin.go index f072327..b41be79 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -12,7 +12,6 @@ import ( "strings" "sync" - bitbucketv1 "github.com/gfleury/go-bitbucket-v1" "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/wbrefvem/go-bitbucket" @@ -22,7 +21,6 @@ import ( "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/plugin" - "github.com/mattermost/mattermost-plugin-bitbucket/server/bitbucketclient" "github.com/mattermost/mattermost-plugin-bitbucket/server/templaterenderer" "github.com/mattermost/mattermost-plugin-bitbucket/server/webhook" ) @@ -107,41 +105,6 @@ func (p *Plugin) bitbucketConnect(token oauth2.Token) *bitbucket.APIClient { return bitbucket.NewAPIClient(configBb) } -func (p *Plugin) bitbucketConnectServer(token oauth2.Token) bitbucketclient.Client { - // get Oauth token source and client - ts := p.getOAuthConfig().TokenSource(context.Background(), &token) - - // setup Oauth context - auth := context.WithValue(context.Background(), bitbucket.ContextOAuth2, ts) - - tc := oauth2.NewClient(auth, ts) - - selfHostedURL := p.configuration.BitbucketSelfHostedURL - apiSelfHostedURL := p.configuration.BitbucketAPISelfHostedURL - - // create config for bitbucket API - configBb := bitbucketv1.NewConfiguration(apiSelfHostedURL) - configBb.HTTPClient = tc - - apiClient := bitbucketv1.NewAPIClient(context.Background(), configBb) - - configClient := bitbucketclient.ClientConfiguration{ - SelfHostedURL: selfHostedURL, - SelfHostedAPIURL: apiSelfHostedURL, - APIClient: apiClient, - OAuthClient: tc, - LogError: p.API.LogError, - } - - bitbucketServer, err := bitbucketclient.GetBitbucketClient("server", configClient) - if err != nil { - p.API.LogError("Error while connecting to bitbucket server", "err", err.Error()) - return nil - } - - return bitbucketServer -} - func (p *Plugin) OnActivate() error { config := p.getConfiguration()