From 568c8372e2034211b232002b4738873987d6c6dc Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 08:58:35 +0200 Subject: [PATCH 01/16] Update build system and config file --- .golangci.yml | 47 ++++++++++++---- Makefile | 72 ++++++++++++++---------- build/custom.mk | 1 + build/deploy/main.go | 122 +++++++++++++++++++++++++++++++++++++++++ build/manifest/main.go | 20 ++++--- build/setup.mk | 9 +++ go.mod | 1 + go.sum | 25 +++++++++ 8 files changed, 251 insertions(+), 46 deletions(-) create mode 100644 build/custom.mk create mode 100644 build/deploy/main.go diff --git a/.golangci.yml b/.golangci.yml index 5f716b517..a43d15986 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,35 +1,62 @@ -service: - golangci-lint-version: 1.23.0 - run: timeout: 5m + modules-download-mode: readonly linters-settings: + goconst: + min-len: 2 + min-occurrences: 2 gofmt: simplify: true + goimports: + local-prefixes: github.com/mattermost/mattermost-plugin-github + golint: + min-confidence: 0 govet: check-shadowing: true enable-all: true + misspell: + locale: US linters: disable-all: true enable: + - bodyclose - deadcode + - errcheck + - goconst + - gocritic - gofmt + - goimports + - golint + - gosec - gosimple - govet - ineffassign + - interfacer + - misspell + - nakedret + - staticcheck - structcheck + - stylecheck + - typecheck - unconvert - unused - varcheck - # TODO: enable this later - # - errcheck + - whitespace issues: exclude-rules: - - linters: - # ignore unused warning for manifest - - varcheck - - deadcode - text: "manifest" + - path: server/manifest.go + linters: + - deadcode + - unused + - varcheck + - path: server/configuration.go + linters: + - unused + - path: _test\.go + linters: + - bodyclose + - goconst + - scopelint # https://github.com/kyoh86/scopelint/issues/4 diff --git a/Makefile b/Makefile index 8f2bd607e..ca7f0bf9f 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ GO ?= $(shell command -v go 2> /dev/null) NPM ?= $(shell command -v npm 2> /dev/null) CURL ?= $(shell command -v curl 2> /dev/null) MANIFEST_FILE ?= plugin.json +GOPATH ?= $(shell go env GOPATH) +GO_TEST_FLAGS ?= -race +GO_BUILD_FLAGS ?= MM_UTILITIES_DIR ?= ../mattermost-utilities export GO111MODULE=on @@ -14,6 +17,11 @@ include build/setup.mk BUNDLE_NAME ?= $(PLUGIN_ID)-$(PLUGIN_VERSION).tar.gz +# Include custom makefile, if present +ifneq ($(wildcard build/custom.mk),) + include build/custom.mk +endif + ## Checks the code style, tests, builds and bundles the plugin. all: check-style test dist @@ -22,7 +30,7 @@ all: check-style test dist apply: ./build/bin/manifest apply -## Runs golangci-lint against all packages. +## Runs golangci-lint and eslint. .PHONY: check-style check-style: webapp/.npminstall golangci-lint @echo Checking for style guide compliance @@ -31,8 +39,9 @@ ifneq ($(HAS_WEBAPP),) cd webapp && npm run lint endif -golangci-lint: ## Run golangci-lint on codebase -# https://stackoverflow.com/a/677212/1027058 (check if a command exists or not) +## Run golangci-lint on codebase. +.PHONY: golangci-lint +golangci-lint: @if ! [ -x "$$(command -v golangci-lint)" ]; then \ echo "golangci-lint is not installed. Please see https://github.com/golangci/golangci-lint#install for installation instructions."; \ exit 1; \ @@ -46,9 +55,9 @@ golangci-lint: ## Run golangci-lint on codebase server: ifneq ($(HAS_SERVER),) mkdir -p server/dist; - cd server && env GOOS=linux GOARCH=amd64 $(GO) build -o dist/plugin-linux-amd64; - cd server && env GOOS=darwin GOARCH=amd64 $(GO) build -o dist/plugin-darwin-amd64; - cd server && env GOOS=windows GOARCH=amd64 $(GO) build -o dist/plugin-windows-amd64.exe; + cd server && env GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-linux-amd64; + cd server && env GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-darwin-amd64; + cd server && env GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-windows-amd64.exe; endif ## Ensures NPM dependencies are installed without having to run this all the time. @@ -65,6 +74,14 @@ ifneq ($(HAS_WEBAPP),) cd webapp && $(NPM) run build; endif +## Builds the webapp in debug mode, if it exists. +.PHONY: webapp-debug +webapp-debug: webapp/.npminstall +ifneq ($(HAS_WEBAPP),) + cd webapp && \ + $(NPM) run debug; +endif + ## Generates a tar bundle of the plugin for install. .PHONY: bundle bundle: @@ -94,39 +111,33 @@ endif dist: apply server webapp bundle ## Installs the plugin to a (development) server. +## It uses the API if appropriate environment variables are defined, +## and otherwise falls back to trying to copy the plugin to a sibling mattermost-server directory. .PHONY: deploy deploy: dist -## It uses the API if appropriate environment variables are defined, -## or copying the files directly to a sibling mattermost-server directory. -ifneq ($(and $(MM_SERVICESETTINGS_SITEURL),$(MM_ADMIN_USERNAME),$(MM_ADMIN_PASSWORD),$(CURL)),) - @echo "Installing plugin via API" - $(eval TOKEN := $(shell curl -i -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/users/login -d '{"login_id": "$(MM_ADMIN_USERNAME)", "password": "$(MM_ADMIN_PASSWORD)"}' | grep Token | cut -f2 -d' ' 2> /dev/null)) - @curl -s -H "Authorization: Bearer $(TOKEN)" -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/plugins -F "plugin=@dist/$(BUNDLE_NAME)" -F "force=true" > /dev/null && \ - curl -s -H "Authorization: Bearer $(TOKEN)" -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/plugins/$(PLUGIN_ID)/enable > /dev/null && \ - echo "OK." || echo "Sorry, something went wrong." -else ifneq ($(wildcard ../mattermost-server/.*),) - @echo "Installing plugin via filesystem. Server restart and manual plugin enabling required" - mkdir -p ../mattermost-server/plugins - tar -C ../mattermost-server/plugins -zxvf dist/$(BUNDLE_NAME) -else - @echo "No supported deployment method available. Install plugin manually." -endif + ./build/bin/deploy $(PLUGIN_ID) dist/$(BUNDLE_NAME) + +.PHONY: debug-deploy +debug-deploy: debug-dist deploy + +.PHONY: debug-dist +debug-dist: apply server webapp-debug bundle ## Runs any lints and unit tests defined for the server and webapp, if they exist. .PHONY: test test: webapp/.npminstall ifneq ($(HAS_SERVER),) - $(GO) test -race -v ./server/... + $(GO) test -v $(GO_TEST_FLAGS) ./server/... endif ifneq ($(HAS_WEBAPP),) - cd webapp && $(NPM) run fix; + cd webapp && $(NPM) run fix && $(NPM) run test; endif ## Creates a coverage report for the server code. .PHONY: coverage -coverage: +coverage: webapp/.npminstall ifneq ($(HAS_SERVER),) - $(GO) test -race -coverprofile=server/coverage.txt ./server/... + $(GO) test $(GO_TEST_FLAGS) -coverprofile=server/coverage.txt ./server/... $(GO) tool cover -html=server/coverage.txt endif @@ -134,8 +145,11 @@ endif .PHONY: i18n-extract i18n-extract: ifneq ($(HAS_WEBAPP),) - @[[ -d $(MM_UTILITIES_DIR) ]] || echo "You must clone github.com/mattermost/mattermost-utilities repo in .. to use this command" - @[[ -d $(MM_UTILITIES_DIR) ]] && cd $(MM_UTILITIES_DIR) && npm install && npm run babel && node mmjstool/build/index.js i18n extract-webapp --webapp-dir ../mattermost-plugin-demo/webapp +ifeq ($(HAS_MM_UTILITIES),) + @echo "You must clone github.com/mattermost/mattermost-utilities repo in .. to use this command" +else + cd $(MM_UTILITIES_DIR) && npm install && npm run babel && node mmjstool/build/index.js i18n extract-webapp --webapp-dir $(PWD)/webapp +endif endif ## Clean removes all build artifacts. @@ -143,15 +157,17 @@ endif clean: rm -fr dist/ ifneq ($(HAS_SERVER),) + rm -fr server/coverage.txt rm -fr server/dist endif ifneq ($(HAS_WEBAPP),) rm -fr webapp/.npminstall + rm -fr webapp/junit.xml rm -fr webapp/dist rm -fr webapp/node_modules endif rm -fr build/bin/ -# Help documentatin à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html +# Help documentation à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html help: @cat Makefile | grep -v '\.PHONY' | grep -v '\help:' | grep -B1 -E '^[a-zA-Z0-9_.-]+:.*' | sed -e "s/:.*//" | sed -e "s/^## //" | grep -v '\-\-' | sed '1!G;h;$$!d' | awk 'NR%2{printf "\033[36m%-30s\033[0m",$$0;next;}1' | sort diff --git a/build/custom.mk b/build/custom.mk new file mode 100644 index 000000000..efad4fbd8 --- /dev/null +++ b/build/custom.mk @@ -0,0 +1 @@ +# Include custome targets and environment variables here diff --git a/build/deploy/main.go b/build/deploy/main.go new file mode 100644 index 000000000..186bb4922 --- /dev/null +++ b/build/deploy/main.go @@ -0,0 +1,122 @@ +// main handles deployment of the plugin to a development server using either the Client4 API +// or by copying the plugin bundle into a sibling mattermost-server/plugin directory. +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + + "github.com/mattermost/mattermost-server/v5/model" + "github.com/mholt/archiver/v3" + "github.com/pkg/errors" +) + +func main() { + err := deploy() + if err != nil { + fmt.Printf("Failed to deploy: %s\n", err.Error()) + fmt.Println() + fmt.Println("Usage:") + fmt.Println(" deploy ") + os.Exit(1) + } +} + +// deploy handles deployment of the plugin to a development server. +func deploy() error { + if len(os.Args) < 3 { + return errors.New("invalid number of arguments") + } + + pluginID := os.Args[1] + bundlePath := os.Args[2] + + siteURL := os.Getenv("MM_SERVICESETTINGS_SITEURL") + adminToken := os.Getenv("MM_ADMIN_TOKEN") + adminUsername := os.Getenv("MM_ADMIN_USERNAME") + adminPassword := os.Getenv("MM_ADMIN_PASSWORD") + copyTargetDirectory, _ := filepath.Abs("../mattermost-server") + + if siteURL != "" { + client := model.NewAPIv4Client(siteURL) + + if adminToken != "" { + log.Printf("Authenticating using token against %s.", siteURL) + client.SetToken(adminToken) + + return uploadPlugin(client, pluginID, bundlePath) + } + + if adminUsername != "" && adminPassword != "" { + client := model.NewAPIv4Client(siteURL) + log.Printf("Authenticating as %s against %s.", adminUsername, siteURL) + _, resp := client.Login(adminUsername, adminPassword) + if resp.Error != nil { + return errors.Wrapf(resp.Error, "failed to login as %s", adminUsername) + } + + return uploadPlugin(client, pluginID, bundlePath) + } + } + + _, err := os.Stat(copyTargetDirectory) + if os.IsNotExist(err) { + return errors.New("no supported deployment method available, please install plugin manually") + } else if err != nil { + return errors.Wrapf(err, "failed to stat %s", copyTargetDirectory) + } + + log.Printf("Installing plugin to mattermost-server found in %s.", copyTargetDirectory) + log.Print("Server restart required to load updated plugin.") + return copyPlugin(pluginID, copyTargetDirectory, bundlePath) +} + +// uploadPlugin attempts to upload and enable a plugin via the Client4 API. +// It will fail if plugin uploads are disabled. +func uploadPlugin(client *model.Client4, pluginID, bundlePath string) error { + pluginBundle, err := os.Open(bundlePath) + if err != nil { + return errors.Wrapf(err, "failed to open %s", bundlePath) + } + defer pluginBundle.Close() + + log.Print("Uploading plugin via API.") + _, resp := client.UploadPluginForced(pluginBundle) + if resp.Error != nil { + return errors.Wrap(resp.Error, "failed to upload plugin bundle") + } + + log.Print("Enabling plugin.") + _, resp = client.EnablePlugin(pluginID) + if resp.Error != nil { + return errors.Wrap(resp.Error, "Failed to enable plugin") + } + + return nil +} + +// copyPlugin attempts to install a plugin by copying it to a sibling ../mattermost-server/plugin +// directory. A server restart is required before the plugin will start. +func copyPlugin(pluginID, targetPath, bundlePath string) error { + targetPath = filepath.Join(targetPath, "plugins") + + err := os.MkdirAll(targetPath, 0777) + if err != nil { + return errors.Wrapf(err, "failed to create %s", targetPath) + } + + existingPluginPath := filepath.Join(targetPath, pluginID) + err = os.RemoveAll(existingPluginPath) + if err != nil { + return errors.Wrapf(err, "failed to remove existing existing plugin directory %s", existingPluginPath) + } + + err = archiver.Unarchive(bundlePath, targetPath) + if err != nil { + return errors.Wrapf(err, "failed to unarchive %s into %s", bundlePath, targetPath) + } + + return nil +} diff --git a/build/manifest/main.go b/build/manifest/main.go index 4bf4e19ad..89a397c1a 100644 --- a/build/manifest/main.go +++ b/build/manifest/main.go @@ -10,18 +10,22 @@ import ( "github.com/pkg/errors" ) -const pluginIdGoFileTemplate = `package main +const pluginIDGoFileTemplate = `// This file is automatically generated. Do not modify it manually. + +package main var manifest = struct { - Id string + ID string Version string }{ - Id: "%s", + ID: "%s", Version: "%s", } ` -const pluginIdJsFileTemplate = `export const id = '%s'; +const pluginIDJSFileTemplate = `// This file is automatically generated. Do not modify it manually. + +export const id = '%s'; export const version = '%s'; ` @@ -38,7 +42,7 @@ func main() { cmd := os.Args[1] switch cmd { case "id": - dumpPluginId(manifest) + dumpPluginID(manifest) case "version": dumpPluginVersion(manifest) @@ -87,7 +91,7 @@ func findManifest() (*model.Manifest, error) { } // dumpPluginId writes the plugin id from the given manifest to standard out -func dumpPluginId(manifest *model.Manifest) { +func dumpPluginID(manifest *model.Manifest) { fmt.Printf("%s", manifest.Id) } @@ -101,7 +105,7 @@ func applyManifest(manifest *model.Manifest) error { if manifest.HasServer() { if err := ioutil.WriteFile( "server/manifest.go", - []byte(fmt.Sprintf(pluginIdGoFileTemplate, manifest.Id, manifest.Version)), + []byte(fmt.Sprintf(pluginIDGoFileTemplate, manifest.Id, manifest.Version)), 0644, ); err != nil { return errors.Wrap(err, "failed to write server/manifest.go") @@ -111,7 +115,7 @@ func applyManifest(manifest *model.Manifest) error { if manifest.HasWebapp() { if err := ioutil.WriteFile( "webapp/src/manifest.js", - []byte(fmt.Sprintf(pluginIdJsFileTemplate, manifest.Id, manifest.Version)), + []byte(fmt.Sprintf(pluginIDJSFileTemplate, manifest.Id, manifest.Version)), 0644, ); err != nil { return errors.Wrap(err, "failed to open webapp/src/manifest.js") diff --git a/build/setup.mk b/build/setup.mk index 13ece2b8c..bc1fdc358 100644 --- a/build/setup.mk +++ b/build/setup.mk @@ -7,6 +7,9 @@ endif # Ensure that the build tools are compiled. Go's caching makes this quick. $(shell cd build/manifest && $(GO) build -o ../bin/manifest) +# Ensure that the deployment tools are compiled. Go's caching makes this quick. +$(shell cd build/deploy && $(GO) build -o ../bin/deploy) + # Extract the plugin id from the manifest. PLUGIN_ID ?= $(shell build/bin/manifest id) ifeq ($(PLUGIN_ID),) @@ -28,6 +31,12 @@ HAS_WEBAPP ?= $(shell build/bin/manifest has_webapp) # Determine if a /public folder is in use HAS_PUBLIC ?= $(wildcard public/.) +# Determine if the mattermost-utilities repo is present +HAS_MM_UTILITIES ?= $(wildcard $(MM_UTILITIES_DIR)/.) + +# Store the current path for later use +PWD ?= $(shell pwd) + # Ensure that npm (and thus node) is installed. ifneq ($(HAS_WEBAPP),) ifeq ($(NPM),) diff --git a/go.mod b/go.mod index 2bb9ac100..b6ee8ef92 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/google/go-github/v25 v25.1.1 github.com/gorilla/mux v1.7.4 github.com/mattermost/mattermost-server/v5 v5.18.0 + github.com/mholt/archiver/v3 v3.3.0 github.com/pkg/errors v0.8.1 github.com/stretchr/testify v1.4.0 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 diff --git a/go.sum b/go.sum index 9c6cf09d9..e7de19fda 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ 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-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6 h1:bZ28Hqta7TFAK3Q08CMvv8y3/8ATaEqv2nGoc6yff6c= +github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -66,6 +68,9 @@ github.com/die-net/lrucache v0.0.0-20181227122439-19a39ef22a11/go.mod h1:ew0MSjC github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= github.com/disintegration/imaging v1.6.1/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 h1:6muCmMJat6z7qptVrIf/+OWPxsjAfvhw5/6t+FwEkgg= github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYia/MIs9OyvXXYboPmNOj0gVWo97Wx0sde+ZuKkoM4= @@ -94,6 +99,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw= +github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -106,10 +113,13 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= @@ -190,6 +200,12 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY= +github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM= +github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -228,6 +244,8 @@ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mholt/archiver/v3 v3.3.0 h1:vWjhY8SQp5yzM9P6OJ/eZEkmi3UAbRrxCq48MxjAzig= +github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08Ebtr1Mqao= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.19/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/minio/minio-go/v6 v6.0.40/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= @@ -253,6 +271,8 @@ github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78Rwc github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= +github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs= +github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -274,6 +294,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/peterbourgon/diskv v0.0.0-20171120014656-2973218375c3/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -347,6 +368,10 @@ github.com/throttled/throttled v2.2.4+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLs github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= From 562fe9ddf977a021cc9291fe93af2a1968cad44d Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 08:59:15 +0200 Subject: [PATCH 02/16] Auto fix --- server/api_test.go | 3 ++- server/command.go | 2 +- server/plugin.go | 3 ++- server/subscriptions_test.go | 4 ++-- server/template_test.go | 3 --- server/testutils/http.go | 8 ++++---- server/utils.go | 4 ++-- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/server/api_test.go b/server/api_test.go index e1d1f0deb..cea15f989 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -1,10 +1,11 @@ package main import ( - "github.com/mattermost/mattermost-plugin-github/server/testutils" "net/http" "net/http/httptest" "testing" + + "github.com/mattermost/mattermost-plugin-github/server/testutils" ) func TestPlugin_ServeHTTP(t *testing.T) { diff --git a/server/command.go b/server/command.go index db29767c2..5993c3cf0 100644 --- a/server/command.go +++ b/server/command.go @@ -185,7 +185,7 @@ func (p *Plugin) handleUnsubscribe(_ *plugin.Context, args *model.CommandArgs, p return "Encountered an error trying to unsubscribe. Please try again." } - return fmt.Sprintf("Succesfully unsubscribed from %s.", repo) + return fmt.Sprintf("Successfully unsubscribed from %s.", repo) } func (p *Plugin) handleDisconnect(_ *plugin.Context, args *model.CommandArgs, _ []string, _ *GitHubUserInfo) string { p.disconnectGitHubAccount(args.UserId) diff --git a/server/plugin.go b/server/plugin.go index b4df81bd2..1cf1cf8d5 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/gorilla/mux" "io/ioutil" "net/http" "net/url" @@ -14,6 +13,8 @@ import ( "strings" "sync" + "github.com/gorilla/mux" + "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin" diff --git a/server/subscriptions_test.go b/server/subscriptions_test.go index a0c6839a5..840e2c786 100644 --- a/server/subscriptions_test.go +++ b/server/subscriptions_test.go @@ -2,9 +2,10 @@ package main import ( "encoding/json" + "testing" + "github.com/mattermost/mattermost-server/v5/plugin/plugintest" "github.com/stretchr/testify/assert" - "testing" ) func CheckError(t *testing.T, wantErr bool, err error) { @@ -41,7 +42,6 @@ func wantedSubscriptions(repoNames []string, chanelID string) []*Subscription { } func TestPlugin_GetSubscriptionsByChannel(t *testing.T) { - type args struct { channelID string } diff --git a/server/template_test.go b/server/template_test.go index 87092761e..81264e99c 100644 --- a/server/template_test.go +++ b/server/template_test.go @@ -180,7 +180,6 @@ git-get-head gets the non-sent upstream heads inside the stashed non-cleaned app }) t.Run("with mentions", withGitHubUserNameMapping(func(t *testing.T) { - expected := ` #### Leverage git-get-head ##### [mattermost-plugin-github#42](https://github.com/mattermost/mattermost-plugin-github/pull/42) @@ -795,7 +794,6 @@ func TestCommentAuthorPullRequestNotificationTemplate(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, actual) - }) t.Run("with mentions", withGitHubUserNameMapping(func(*testing.T) { @@ -816,7 +814,6 @@ func TestCommentAuthorPullRequestNotificationTemplate(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, actual) - })) } diff --git a/server/testutils/http.go b/server/testutils/http.go index c6becb0ac..4e5141f38 100644 --- a/server/testutils/http.go +++ b/server/testutils/http.go @@ -3,12 +3,13 @@ package testutils import ( "bytes" "encoding/json" - "github.com/pkg/errors" - "github.com/stretchr/testify/assert" "io" "net/http" "net/http/httptest" "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" ) const ( @@ -32,7 +33,7 @@ type Request struct { Body interface{} } -// ExpectedResponse stores expected responce basic data +// ExpectedResponse stores expected response basic data type ExpectedResponse struct { StatusCode int ResponseType contentType @@ -56,7 +57,6 @@ func EncodeJSON(data interface{}) ([]byte, error) { } return b, nil - } // EncodeJSON encodes json data in bytes diff --git a/server/utils.go b/server/utils.go index 0a7454246..1517ec9f5 100644 --- a/server/utils.go +++ b/server/utils.go @@ -99,7 +99,7 @@ func decrypt(key []byte, text string) (string, error) { } if (len(decodedMsg) % aes.BlockSize) != 0 { - return "", errors.New("blocksize must be multipe of decoded message length") + return "", errors.New("blocksize must be multiple of decoded message length") } iv := decodedMsg[:aes.BlockSize] @@ -256,7 +256,7 @@ func getLine(s string) int { return line } -// isInsideLink reports whether the given index in a string is preceeded +// isInsideLink reports whether the given index in a string is preceded // by zero or more space, then (, then ]. // // It is a poor man's version of checking markdown hyperlinks without From 0b44be3249ad36bc18323308c1b1995b97e49047 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 09:39:31 +0200 Subject: [PATCH 03/16] Fix simple errors --- .golangci.yml | 4 +- server/api.go | 223 +++++++++++++++-------------------- server/api_test.go | 4 +- server/command.go | 28 +++-- server/configuration.go | 6 +- server/manifest.go | 6 +- server/plugin.go | 54 +++++---- server/subscriptions.go | 34 +++--- server/subscriptions_test.go | 2 +- server/webhook.go | 10 +- webapp/src/manifest.js | 2 + 11 files changed, 178 insertions(+), 195 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a43d15986..0ae6c0649 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,8 +23,8 @@ linters: enable: - bodyclose - deadcode - - errcheck - - goconst + #- errcheck + #- goconst - gocritic - gofmt - goimports diff --git a/server/api.go b/server/api.go index 634f45209..ce6afacea 100644 --- a/server/api.go +++ b/server/api.go @@ -21,7 +21,7 @@ import ( ) const ( - API_ERROR_ID_NOT_CONNECTED = "not_connected" + apiErrorIDNotConnected = "not_connected" // the OAuth token expiry in seconds TokenTTL = 10 * 60 ) @@ -202,7 +202,7 @@ func (p *Plugin) completeConnectUserToGitHub(w http.ResponseWriter, r *http.Requ GitHubUsername: gitUser.GetLogin(), LastToDoPostAt: model.GetMillis(), Settings: &UserSettings{ - SidebarButtons: SETTING_BUTTONS_TEAM, + SidebarButtons: settingButtonsTeam, DailyReminder: true, Notifications: true, }, @@ -237,13 +237,13 @@ func (p *Plugin) completeConnectUserToGitHub(w http.ResponseWriter, r *http.Requ "* The fifth will refresh the numbers.\n\n"+ "Click on them!\n\n"+ "##### Slash Commands\n"+ - strings.Replace(COMMAND_HELP, "|", "`", -1), gitUser.GetLogin(), gitUser.GetHTMLURL()) + strings.Replace(commandHelp, "|", "`", -1), gitUser.GetLogin(), gitUser.GetHTMLURL()) p.CreateBotDMPost(state.UserID, message, "custom_git_welcome") config := p.getConfiguration() p.API.PublishWebSocketEvent( - WS_EVENT_CONNECT, + wsEventConnect, map[string]interface{}{ "connected": true, "github_username": userInfo.GitHubUsername, @@ -282,7 +282,7 @@ type ConnectedResponse struct { } type CreateIssueCommentRequest struct { - PostId string `json:"post_id"` + PostID string `json:"post_id"` Owner string `json:"owner"` Repo string `json:"repo"` Number int `json:"number"` @@ -300,18 +300,20 @@ type GitHubUserResponse struct { func (p *Plugin) getGitHubUser(w http.ResponseWriter, r *http.Request, _ string) { req := &GitHubUserRequest{} - dec := json.NewDecoder(r.Body) - if err := dec.Decode(&req); err != nil || req.UserID == "" { - if err != nil { - mlog.Error("Error decoding JSON body: " + err.Error()) - } + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + mlog.Error("Error decoding JSON body", mlog.Err(err)) + writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) + return + } + + if req.UserID == "" { writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object with a non-blank user_id field.", StatusCode: http.StatusBadRequest}) return } userInfo, apiErr := p.getGitHubUserInfo(req.UserID) if apiErr != nil { - if apiErr.ID == API_ERROR_ID_NOT_CONNECTED { + if apiErr.ID == apiErrorIDNotConnected { writeAPIError(w, &APIErrorResponse{ID: "", Message: "User is not connected to a GitHub account.", StatusCode: http.StatusNotFound}) } else { writeAPIError(w, apiErr) @@ -325,10 +327,11 @@ func (p *Plugin) getGitHubUser(w http.ResponseWriter, r *http.Request, _ string) } resp := &GitHubUserResponse{Username: userInfo.GitHubUsername} - b, jsonErr := json.Marshal(resp) - if jsonErr != nil { - mlog.Error("Error encoding JSON response: " + jsonErr.Error()) + b, err := json.Marshal(resp) + if err != nil { + mlog.Error("Error encoding JSON response: " + err.Error()) writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an unexpected error. Please try again.", StatusCode: http.StatusInternalServerError}) + return } w.Write(b) } @@ -369,14 +372,14 @@ func (p *Plugin) getConnected(w http.ResponseWriter, r *http.Request, userID str } } - privateRepoStoreKey := info.UserID + GITHUB_PRIVATE_REPO_KEY + privateRepoStoreKey := info.UserID + githubPrivateRepoKey if config.EnablePrivateRepo && !info.AllowedPrivateRepos { hasBeenNotified := false - if val, err := p.API.KVGet(privateRepoStoreKey); err == nil { - hasBeenNotified = val != nil - } else { + val, err := p.API.KVGet(privateRepoStoreKey) + if err != nil { mlog.Error("Unable to get private repo key value, err=" + err.Error()) } + hasBeenNotified = val != nil if !hasBeenNotified { p.CreateBotDMPost(info.UserID, "Private repositories have been enabled for this plugin. To be able to use them you must disconnect and reconnect your GitHub account. To reconnect your account, use the following slash commands: `/github disconnect` followed by `/github connect private`.", "") @@ -394,22 +397,19 @@ func (p *Plugin) getConnected(w http.ResponseWriter, r *http.Request, userID str func (p *Plugin) getMentions(w http.ResponseWriter, r *http.Request, userID string) { config := p.getConfiguration() - ctx := context.Background() - - var githubClient *github.Client - username := "" - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) - username = info.GitHubUsername } - result, _, err := githubClient.Search.Issues(ctx, getMentionSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) + githubClient := p.githubConnect(*info.Token) + username := info.GitHubUsername + + result, _, err := githubClient.Search.Issues(context.Background(), getMentionSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return } resp, _ := json.Marshal(result.Issues) @@ -419,18 +419,18 @@ func (p *Plugin) getMentions(w http.ResponseWriter, r *http.Request, userID stri func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID string) { ctx := context.Background() - var githubClient *github.Client - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) } + githubClient := p.githubConnect(*info.Token) + notifications, _, err := githubClient.Activity.ListNotifications(ctx, &github.NotificationListOptions{}) if err != nil { mlog.Error(err.Error()) + return } type filteredNotification struct { @@ -462,22 +462,19 @@ func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID strin func (p *Plugin) getReviews(w http.ResponseWriter, r *http.Request, userID string) { config := p.getConfiguration() - ctx := context.Background() - - var githubClient *github.Client - username := "" - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) - username = info.GitHubUsername } - result, _, err := githubClient.Search.Issues(ctx, getReviewSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) + githubClient := p.githubConnect(*info.Token) + username := info.GitHubUsername + + result, _, err := githubClient.Search.Issues(context.Background(), getReviewSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return } resp, _ := json.Marshal(result.Issues) @@ -487,22 +484,19 @@ func (p *Plugin) getReviews(w http.ResponseWriter, r *http.Request, userID strin func (p *Plugin) getYourPrs(w http.ResponseWriter, r *http.Request, userID string) { config := p.getConfiguration() - ctx := context.Background() - - var githubClient *github.Client - username := "" - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) - username = info.GitHubUsername } - result, _, err := githubClient.Search.Issues(ctx, getYourPrsSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) + githubClient := p.githubConnect(*info.Token) + username := info.GitHubUsername + + result, _, err := githubClient.Search.Issues(context.Background(), getYourPrsSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return } resp, _ := json.Marshal(result.Issues) @@ -510,25 +504,20 @@ func (p *Plugin) getYourPrs(w http.ResponseWriter, r *http.Request, userID strin } func (p *Plugin) getPrsDetails(w http.ResponseWriter, r *http.Request, userID string) { - ctx := context.Background() - - var githubClient *github.Client - info, err := p.getGitHubUserInfo(userID) - if err != nil { writeAPIError(w, err) return } - githubClient = p.githubConnect(*info.Token) + githubClient := p.githubConnect(*info.Token) var prList []*PRDetails json.NewDecoder(r.Body).Decode(&prList) prDetails := make([]*PRDetails, len(prList)) + ctx := context.Background() var wg sync.WaitGroup - for i, pr := range prList { i := i pr := pr @@ -616,35 +605,28 @@ func getRepoOwnerAndNameFromURL(url string) (string, string) { func (p *Plugin) searchIssues(w http.ResponseWriter, r *http.Request, userID string) { config := p.getConfiguration() - if r.Method != http.MethodGet { - http.Error(w, fmt.Sprintf("Request: %s is not allowed, must be GET", r.Method), http.StatusMethodNotAllowed) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return } - ctx := context.Background() - - var githubClient *github.Client + githubClient := p.githubConnect(*info.Token) searchTerm := r.FormValue("term") - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) - return - } else { - githubClient = p.githubConnect(*info.Token) - } - - result, _, err := githubClient.Search.Issues(ctx, getIssuesSearchQuery(config.GitHubOrg, searchTerm), &github.SearchOptions{}) + result, _, err := githubClient.Search.Issues(context.Background(), getIssuesSearchQuery(config.GitHubOrg, searchTerm), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return } resp, _ := json.Marshal(result.Issues) w.Write(resp) } -func getPermaLink(siteUrl string, postId string, currentTeam string) string { - return fmt.Sprintf("%v/%v/pl/%v", siteUrl, currentTeam, postId) +func getPermaLink(siteURL string, postID string, currentTeam string) string { + return fmt.Sprintf("%v/%v/pl/%v", siteURL, currentTeam, postID) } func getFailReason(code int, repo string, username string) string { @@ -668,14 +650,13 @@ func getFailReason(code int, repo string, username string) string { func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, userID string) { req := &CreateIssueCommentRequest{} - dec := json.NewDecoder(r.Body) - if err := dec.Decode(&req); err != nil { + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { mlog.Error("Error decoding JSON body", mlog.Err(err)) writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) return } - if req.PostId == "" { + if req.PostID == "" { writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid post id", StatusCode: http.StatusBadRequest}) return } @@ -705,43 +686,38 @@ func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, user return } - ctx := context.Background() - - var githubClient *github.Client - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) } - api := p.API - post, appErr := api.GetPost(req.PostId) + githubClient := p.githubConnect(*info.Token) + + post, appErr := p.API.GetPost(req.PostID) if appErr != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostId, StatusCode: http.StatusInternalServerError}) + writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostID, StatusCode: http.StatusInternalServerError}) return } if post == nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostId + ": not found", StatusCode: http.StatusNotFound}) + writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostID + ": not found", StatusCode: http.StatusNotFound}) return } - commentUser, appErr := api.GetUser(post.UserId) + commentUser, appErr := p.API.GetUser(post.UserId) if appErr != nil { writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post.UserID " + post.UserId + ": not found", StatusCode: http.StatusInternalServerError}) return } - currentUser, appErr := api.GetUser(userID) + currentUser, appErr := p.API.GetUser(userID) if appErr != nil { writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load current user", StatusCode: http.StatusInternalServerError}) return } - siteUrl := api.GetConfig().ServiceSettings.SiteURL - - permalink := getPermaLink(*siteUrl, req.PostId, req.CurrentTeam) + siteURL := *p.API.GetConfig().ServiceSettings.SiteURL + permalink := getPermaLink(siteURL, req.PostID, req.CurrentTeam) permalinkMessage := fmt.Sprintf("*@%s attached a* [message](%s) *from @%s*\n", currentUser.Username, permalink, commentUser.Username) @@ -750,28 +726,28 @@ func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, user Body: &req.Comment, } - result, rawResponse, err := githubClient.Issues.CreateComment(ctx, req.Owner, req.Repo, req.Number, comment) + result, rawResponse, err := githubClient.Issues.CreateComment(context.Background(), req.Owner, req.Repo, req.Number, comment) if err != nil { writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create an issue comment: " + getFailReason(rawResponse.StatusCode, req.Repo, currentUser.Username), StatusCode: rawResponse.StatusCode}) return } - rootId := req.PostId + rootID := req.PostID if post.RootId != "" { // the original post was a reply - rootId = post.RootId + rootID = post.RootId } reply := &model.Post{ Message: fmt.Sprintf("Message attached to [#%v](https://github.com/%v/%v/issues/%v)", req.Number, req.Owner, req.Repo, req.Number), ChannelId: post.ChannelId, - RootId: rootId, - ParentId: rootId, + RootId: rootID, + ParentId: rootID, UserId: userID, } - _, appErr = api.CreatePost(reply) + _, appErr = p.API.CreatePost(reply) if appErr != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create notification post " + req.PostId, StatusCode: http.StatusInternalServerError}) + writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create notification post " + req.PostID, StatusCode: http.StatusInternalServerError}) return } resp, _ := json.Marshal(result) @@ -781,22 +757,19 @@ func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, user func (p *Plugin) getYourAssignments(w http.ResponseWriter, r *http.Request, userID string) { config := p.getConfiguration() - ctx := context.Background() - - var githubClient *github.Client - username := "" - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) - username = info.GitHubUsername } - result, _, err := githubClient.Search.Issues(ctx, getYourAssigneeSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) + githubClient := p.githubConnect(*info.Token) + username := info.GitHubUsername + + result, _, err := githubClient.Search.Issues(context.Background(), getYourAssigneeSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return } resp, _ := json.Marshal(result.Issues) @@ -804,17 +777,15 @@ func (p *Plugin) getYourAssignments(w http.ResponseWriter, r *http.Request, user } func (p *Plugin) postToDo(w http.ResponseWriter, r *http.Request, userID string) { - var githubClient *github.Client - username := "" - - if info, err := p.getGitHubUserInfo(userID); err != nil { - writeAPIError(w, err) + info, apiErr := p.getGitHubUserInfo(userID) + if apiErr != nil { + writeAPIError(w, apiErr) return - } else { - githubClient = p.githubConnect(*info.Token) - username = info.GitHubUsername } + githubClient := p.githubConnect(*info.Token) + username := info.GitHubUsername + text, err := p.GetToDo(context.Background(), username, githubClient) if err != nil { mlog.Error(err.Error()) @@ -824,6 +795,7 @@ func (p *Plugin) postToDo(w http.ResponseWriter, r *http.Request, userID string) if err := p.CreateBotDMPost(userID, text, "custom_git_todo"); err != nil { writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an error posting the to do items.", StatusCode: http.StatusUnauthorized}) + return } w.Write([]byte("{\"status\": \"OK\"}")) @@ -848,6 +820,7 @@ func (p *Plugin) updateSettings(w http.ResponseWriter, r *http.Request, userID s if err := p.storeGitHubUserInfo(info); err != nil { mlog.Error(err.Error()) http.Error(w, "Encountered error updating settings", http.StatusInternalServerError) + return } resp, _ := json.Marshal(info.Settings) diff --git a/server/api_test.go b/server/api_test.go index cea15f989..c53cf25da 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -9,7 +9,7 @@ import ( ) func TestPlugin_ServeHTTP(t *testing.T) { - httpTestJson := testutils.HTTPTest{ + httpTestJSON := testutils.HTTPTest{ T: t, Encoder: testutils.EncodeJSON, } @@ -28,7 +28,7 @@ func TestPlugin_ServeHTTP(t *testing.T) { }{ { name: "unauthorized test json", - httpTest: httpTestJson, + httpTest: httpTestJSON, request: testutils.Request{ Method: "GET", URL: "/api/v1/connected", diff --git a/server/command.go b/server/command.go index 5993c3cf0..3448eaa62 100644 --- a/server/command.go +++ b/server/command.go @@ -12,7 +12,7 @@ import ( "github.com/mattermost/mattermost-server/v5/model" ) -const COMMAND_HELP = `* |/github connect [private]| - Connect your Mattermost account to your GitHub account. +const commandHelp = `* |/github connect [private]| - Connect your Mattermost account to your GitHub account. * |private| is optional. If used, the github bot will ask for read access to your private repositories. If these repositories send webhook events to this Mattermost server, you will be notified of changes to those repositories. * |/github disconnect| - Disconnect your Mattermost account from your GitHub account * |/github todo| - Get a list of unread messages and pull requests awaiting your review @@ -106,9 +106,10 @@ func (p *Plugin) handleSubscribe(_ *plugin.Context, args *model.CommandArgs, par flags := SubscriptionFlags{} txt := "" - if len(parameters) == 0 { + switch { + case len(parameters) == 0: return "Please specify a repository or 'list' command." - } else if len(parameters) == 1 && parameters[0] == "list" { + case len(parameters) == 1 && parameters[0] == "list": subs, err := p.GetSubscriptionsByChannel(args.ChannelId) if err != nil { return err.Error() @@ -128,7 +129,7 @@ func (p *Plugin) handleSubscribe(_ *plugin.Context, args *model.CommandArgs, par txt += "\n" } return txt - } else if len(parameters) > 1 { + case len(parameters) > 1: var optionList []string for _, element := range parameters[1:] { @@ -214,11 +215,11 @@ func (p *Plugin) handleMe(_ *plugin.Context, _ *model.CommandArgs, _ []string, u return text } func (p *Plugin) handleHelp(_ *plugin.Context, _ *model.CommandArgs, _ []string, _ *GitHubUserInfo) string { - text := "###### Mattermost GitHub Plugin - Slash Command Help\n" + strings.Replace(COMMAND_HELP, "|", "`", -1) + text := "###### Mattermost GitHub Plugin - Slash Command Help\n" + strings.Replace(commandHelp, "|", "`", -1) return text } func (p *Plugin) handleEmpty(_ *plugin.Context, _ *model.CommandArgs, _ []string, _ *GitHubUserInfo) string { - text := "###### Mattermost GitHub Plugin - Slash Command Help\n" + strings.Replace(COMMAND_HELP, "|", "`", -1) + text := "###### Mattermost GitHub Plugin - Slash Command Help\n" + strings.Replace(commandHelp, "|", "`", -1) return text } func (p *Plugin) handleSettings(_ *plugin.Context, _ *model.CommandArgs, parameters []string, userInfo *GitHubUserInfo) string { @@ -227,39 +228,40 @@ func (p *Plugin) handleSettings(_ *plugin.Context, _ *model.CommandArgs, paramet } setting := parameters[0] - if setting != SETTING_NOTIFICATIONS && setting != SETTING_REMINDERS { + if setting != settingNotifications && setting != settingReminders { return "Unknown setting." } strValue := parameters[1] value := false - if strValue == SETTING_ON { + if strValue == settingOn { value = true - } else if strValue != SETTING_OFF { + } else if strValue != settingOff { return "Invalid value. Accepted values are: \"on\" or \"off\"." } - if setting == SETTING_NOTIFICATIONS { + if setting == settingNotifications { if value { err := p.storeGitHubToUserIDMapping(userInfo.GitHubUsername, userInfo.UserID) if err != nil { mlog.Error(err.Error()) } } else { - err := p.API.KVDelete(userInfo.GitHubUsername + GITHUB_USERNAME_KEY) + err := p.API.KVDelete(userInfo.GitHubUsername + githubUsernameKey) if err != nil { mlog.Error(err.Error()) } } userInfo.Settings.Notifications = value - } else if setting == SETTING_REMINDERS { + } else if setting == settingReminders { userInfo.Settings.DailyReminder = value } err := p.storeGitHubUserInfo(userInfo) if err != nil { mlog.Error(err.Error()) + return "Failed to store settings" } return "Settings updated." @@ -302,7 +304,7 @@ func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*mo info, apiErr := p.getGitHubUserInfo(args.UserId) if apiErr != nil { text := "Unknown error." - if apiErr.ID == API_ERROR_ID_NOT_CONNECTED { + if apiErr.ID == apiErrorIDNotConnected { text = "You must connect your account to GitHub first. Either click on the GitHub logo in the bottom left of the screen or enter `/github connect`." } p.postCommandResponse(args, text) diff --git a/server/configuration.go b/server/configuration.go index 3f37ab716..49ae1979b 100644 --- a/server/configuration.go +++ b/server/configuration.go @@ -40,15 +40,15 @@ func (c *configuration) Clone() *configuration { // IsValid checks if all needed fields are set. func (c *configuration) IsValid() error { if c.GitHubOAuthClientID == "" { - return fmt.Errorf("Must have a github oauth client id") + return fmt.Errorf("must have a github oauth client id") } if c.GitHubOAuthClientSecret == "" { - return fmt.Errorf("Must have a github oauth client secret") + return fmt.Errorf("must have a github oauth client secret") } if c.EncryptionKey == "" { - return fmt.Errorf("Must have an encryption key") + return fmt.Errorf("must have an encryption key") } return nil diff --git a/server/manifest.go b/server/manifest.go index 343af0678..4c36dc1a4 100644 --- a/server/manifest.go +++ b/server/manifest.go @@ -1,9 +1,11 @@ +// This file is automatically generated. Do not modify it manually. + package main var manifest = struct { - Id string + ID string Version string }{ - Id: "github", + ID: "github", Version: "0.14.0", } diff --git a/server/plugin.go b/server/plugin.go index 1cf1cf8d5..a4cbc4603 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -25,17 +25,17 @@ import ( ) const ( - GITHUB_TOKEN_KEY = "_githubtoken" - GITHUB_USERNAME_KEY = "_githubusername" - GITHUB_PRIVATE_REPO_KEY = "_githubprivate" - WS_EVENT_CONNECT = "connect" - WS_EVENT_DISCONNECT = "disconnect" - WS_EVENT_REFRESH = "refresh" - SETTING_BUTTONS_TEAM = "team" - SETTING_NOTIFICATIONS = "notifications" - SETTING_REMINDERS = "reminders" - SETTING_ON = "on" - SETTING_OFF = "off" + githubTokenKey = "_githubtoken" + githubUsernameKey = "_githubusername" + githubPrivateRepoKey = "_githubprivate" + wsEventConnect = "connect" + wsEventDisconnect = "disconnect" + wsEventRefresh = "refresh" + settingButtonsTeam = "team" + settingNotifications = "notifications" + settingReminders = "reminders" + settingOn = "on" + settingOff = "off" ) type Plugin struct { @@ -113,7 +113,7 @@ func (p *Plugin) OnActivate() error { p.API.RegisterCommand(getCommand()) - botId, err := p.Helpers.EnsureBot(&model.Bot{ + botID, err := p.Helpers.EnsureBot(&model.Bot{ Username: "github", DisplayName: "GitHub", Description: "Created by the GitHub plugin.", @@ -121,7 +121,7 @@ func (p *Plugin) OnActivate() error { if err != nil { return errors.Wrap(err, "failed to ensure github bot") } - p.BotUserID = botId + p.BotUserID = botID bundlePath, err := p.API.GetBundlePath() if err != nil { @@ -133,7 +133,7 @@ func (p *Plugin) OnActivate() error { return errors.Wrap(err, "couldn't read profile image") } - appErr := p.API.SetProfileImage(botId, profileImage) + appErr := p.API.SetProfileImage(botID, profileImage) if appErr != nil { return errors.Wrap(appErr, "couldn't set profile image") } @@ -228,7 +228,7 @@ func (p *Plugin) storeGitHubUserInfo(info *GitHubUserInfo) error { return err } - if err := p.API.KVSet(info.UserID+GITHUB_TOKEN_KEY, jsonInfo); err != nil { + if err := p.API.KVSet(info.UserID+githubTokenKey, jsonInfo); err != nil { return err } @@ -240,8 +240,8 @@ func (p *Plugin) getGitHubUserInfo(userID string) (*GitHubUserInfo, *APIErrorRes var userInfo GitHubUserInfo - if infoBytes, err := p.API.KVGet(userID + GITHUB_TOKEN_KEY); err != nil || infoBytes == nil { - return nil, &APIErrorResponse{ID: API_ERROR_ID_NOT_CONNECTED, Message: "Must connect user account to GitHub first.", StatusCode: http.StatusBadRequest} + if infoBytes, err := p.API.KVGet(userID + githubTokenKey); err != nil || infoBytes == nil { + return nil, &APIErrorResponse{ID: apiErrorIDNotConnected, Message: "Must connect user account to GitHub first.", StatusCode: http.StatusBadRequest} } else if err := json.Unmarshal(infoBytes, &userInfo); err != nil { return nil, &APIErrorResponse{ID: "", Message: "Unable to parse token.", StatusCode: http.StatusInternalServerError} } @@ -258,14 +258,14 @@ func (p *Plugin) getGitHubUserInfo(userID string) (*GitHubUserInfo, *APIErrorRes } func (p *Plugin) storeGitHubToUserIDMapping(githubUsername, userID string) error { - if err := p.API.KVSet(githubUsername+GITHUB_USERNAME_KEY, []byte(userID)); err != nil { - return fmt.Errorf("Encountered error saving github username mapping") + if err := p.API.KVSet(githubUsername+githubUsernameKey, []byte(userID)); err != nil { + return fmt.Errorf("encountered error saving github username mapping") } return nil } func (p *Plugin) getGitHubToUserIDMapping(githubUsername string) string { - userID, _ := p.API.KVGet(githubUsername + GITHUB_USERNAME_KEY) + userID, _ := p.API.KVGet(githubUsername + githubUsernameKey) return string(userID) } @@ -285,8 +285,8 @@ func (p *Plugin) disconnectGitHubAccount(userID string) { return } - p.API.KVDelete(userID + GITHUB_TOKEN_KEY) - p.API.KVDelete(userInfo.GitHubUsername + GITHUB_USERNAME_KEY) + p.API.KVDelete(userID + githubTokenKey) + p.API.KVDelete(userInfo.GitHubUsername + githubUsernameKey) if user, err := p.API.GetUser(userID); err == nil && user.Props != nil && len(user.Props["git_user"]) > 0 { delete(user.Props, "git_user") @@ -294,7 +294,7 @@ func (p *Plugin) disconnectGitHubAccount(userID string) { } p.API.PublishWebSocketEvent( - WS_EVENT_DISCONNECT, + wsEventDisconnect, nil, &model.WebsocketBroadcast{UserId: userID}, ) @@ -443,22 +443,26 @@ func (p *Plugin) HasUnreads(info *GitHubUserInfo) bool { issues, _, err := githubClient.Search.Issues(ctx, getReviewSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return false } yourPrs, _, err := githubClient.Search.Issues(ctx, getYourPrsSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return false } yourAssignments, _, err := githubClient.Search.Issues(ctx, getYourAssigneeSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { mlog.Error(err.Error()) + return false } relevantNotifications := false notifications, _, err := githubClient.Activity.ListNotifications(ctx, &github.NotificationListOptions{}) if err != nil { mlog.Error(err.Error()) + return false } for _, n := range notifications { @@ -491,7 +495,7 @@ func (p *Plugin) checkOrg(org string) error { configOrg := strings.TrimSpace(config.GitHubOrg) if configOrg != "" && configOrg != org { - return fmt.Errorf("Only repositories in the %v organization are supported", configOrg) + return fmt.Errorf("only repositories in the %v organization are supported", configOrg) } return nil @@ -513,7 +517,7 @@ func (p *Plugin) isUserOrganizationMember(githubClient *github.Client, user *git func (p *Plugin) sendRefreshEvent(userID string) { p.API.PublishWebSocketEvent( - WS_EVENT_REFRESH, + wsEventRefresh, nil, &model.WebsocketBroadcast{UserId: userID}, ) diff --git a/server/subscriptions.go b/server/subscriptions.go index 4d6c80eb6..2ad15cd79 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -14,8 +14,8 @@ import ( ) const ( - SUBSCRIPTIONS_KEY = "subscriptions" - EXCLUDE_ORG_MEMBER_FLAG = "exclude-org-member" + subcriptionsKey = "subscriptions" + excludeOrgMemberFlag = "exclude-org-member" ) type SubscriptionFlags struct { @@ -23,8 +23,8 @@ type SubscriptionFlags struct { } func (s *SubscriptionFlags) AddFlag(flag string) { - switch flag { - case EXCLUDE_ORG_MEMBER_FLAG: + switch flag { // nolint:gocritic + case excludeOrgMemberFlag: s.ExcludeOrgMembers = true } } @@ -33,7 +33,7 @@ func (s SubscriptionFlags) String() string { flags := []string{} if s.ExcludeOrgMembers { - flag := "--" + EXCLUDE_ORG_MEMBER_FLAG + flag := "--" + excludeOrgMemberFlag flags = append(flags, flag) } @@ -97,9 +97,9 @@ func (s *Subscription) ExcludeOrgMembers() bool { return s.Flags.ExcludeOrgMembers } -func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, userId, owner, repo, channelID, features string, flags SubscriptionFlags) error { +func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, userID, owner, repo, channelID, features string, flags SubscriptionFlags) error { if owner == "" { - return fmt.Errorf("Invalid repository") + return fmt.Errorf("invalid repository") } if err := p.checkOrg(owner); err != nil { @@ -115,7 +115,7 @@ func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, use var ghUser *github.User ghUser, _, err = githubClient.Users.Get(ctx, owner) if ghUser == nil { - return fmt.Errorf("Unknown organization %s", owner) + return fmt.Errorf("unknown organization %s", owner) } } } else { @@ -123,18 +123,18 @@ func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, use ghRepo, _, err = githubClient.Repositories.Get(ctx, owner, repo) if ghRepo == nil { - return fmt.Errorf("Unknown repository %s", fullNameFromOwnerAndRepo(owner, repo)) + return fmt.Errorf("unknown repository %s", fullNameFromOwnerAndRepo(owner, repo)) } } if err != nil { mlog.Error(err.Error()) - return fmt.Errorf("Encountered an error subscribing to %s", fullNameFromOwnerAndRepo(owner, repo)) + return fmt.Errorf("encountered an error subscribing to %s", fullNameFromOwnerAndRepo(owner, repo)) } sub := &Subscription{ ChannelID: channelID, - CreatorID: userId, + CreatorID: userID, Features: features, Repository: fullNameFromOwnerAndRepo(owner, repo), Flags: flags, @@ -147,12 +147,12 @@ func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, use return nil } -func (p *Plugin) SubscribeOrg(ctx context.Context, githubClient *github.Client, userId, org, channelID, features string, flags SubscriptionFlags) error { +func (p *Plugin) SubscribeOrg(ctx context.Context, githubClient *github.Client, userID, org, channelID, features string, flags SubscriptionFlags) error { if org == "" { - return fmt.Errorf("Invalid organization") + return fmt.Errorf("envalid organization") } - return p.Subscribe(ctx, githubClient, userId, org, "", channelID, features, flags) + return p.Subscribe(ctx, githubClient, userID, org, "", channelID, features, flags) } func (p *Plugin) GetSubscriptionsByChannel(channelID string) ([]*Subscription, error) { @@ -218,7 +218,7 @@ func (p *Plugin) AddSubscription(repo string, sub *Subscription) error { func (p *Plugin) GetSubscriptions() (*Subscriptions, error) { var subscriptions *Subscriptions - value, err := p.API.KVGet(SUBSCRIPTIONS_KEY) + value, err := p.API.KVGet(subcriptionsKey) if err != nil { return nil, err } @@ -237,7 +237,7 @@ func (p *Plugin) StoreSubscriptions(s *Subscriptions) error { if err != nil { return err } - p.API.KVSet(SUBSCRIPTIONS_KEY, b) + p.API.KVSet(subcriptionsKey, b) return nil } @@ -282,7 +282,7 @@ func (p *Plugin) Unsubscribe(channelID string, repo string) error { owner, repo := parseOwnerAndRepo(repo, config.EnterpriseBaseURL) if owner == "" && repo == "" { - return fmt.Errorf("Invalid repository") + return fmt.Errorf("envalid repository") } repoWithOwner := fmt.Sprintf("%s/%s", owner, repo) diff --git a/server/subscriptions_test.go b/server/subscriptions_test.go index 840e2c786..b7162c3ed 100644 --- a/server/subscriptions_test.go +++ b/server/subscriptions_test.go @@ -24,7 +24,7 @@ func pluginWithMockedSubs(subscriptions []*Subscription) *Plugin { subs := Subscriptions{Repositories: map[string][]*Subscription{}} subs.Repositories[""] = subscriptions jsn, _ := json.Marshal(subs) - mockPluginAPI.On("KVGet", SUBSCRIPTIONS_KEY).Return(jsn, nil) + mockPluginAPI.On("KVGet", subcriptionsKey).Return(jsn, nil) p.SetAPI(mockPluginAPI) return p } diff --git a/server/webhook.go b/server/webhook.go index bfaec93f3..375bcae79 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -3,7 +3,7 @@ package main import ( "context" "crypto/hmac" - "crypto/sha1" + "crypto/sha1" //nolint:gosec "encoding/hex" "fmt" "io/ioutil" @@ -705,16 +705,16 @@ func (p *Plugin) handleCommentMentionNotification(event *github.IssueCommentEven continue } - userId := p.getGitHubToUserIDMapping(username) - if userId == "" { + userID := p.getGitHubToUserIDMapping(username) + if userID == "" { continue } - if event.GetRepo().GetPrivate() && !p.permissionToRepo(userId, event.GetRepo().GetFullName()) { + if event.GetRepo().GetPrivate() && !p.permissionToRepo(userID, event.GetRepo().GetFullName()) { continue } - channel, err := p.API.GetDirectChannel(userId, p.BotUserID) + channel, err := p.API.GetDirectChannel(userID, p.BotUserID) if err != nil { continue } diff --git a/webapp/src/manifest.js b/webapp/src/manifest.js index 50d17b64f..3aace0030 100644 --- a/webapp/src/manifest.js +++ b/webapp/src/manifest.js @@ -1,2 +1,4 @@ +// This file is automatically generated. Do not modify it manually. + export const id = 'github'; export const version = '0.14.0'; From 135bb8988c87b62de56140b077ea1309a0ceb2f8 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 11:30:18 +0200 Subject: [PATCH 04/16] Enable goconst --- .golangci.yml | 5 ++++- server/api.go | 6 ++---- server/command.go | 20 ++++++++++--------- server/plugin.go | 44 +++++++++++++++++++++++++---------------- server/subscriptions.go | 8 +++----- server/utils.go | 7 +------ server/utils_test.go | 19 ++++++++++-------- server/webhook.go | 6 ++---- 8 files changed, 61 insertions(+), 54 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 0ae6c0649..abec547a0 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -24,7 +24,7 @@ linters: - bodyclose - deadcode #- errcheck - #- goconst + - goconst - gocritic - gofmt - goimports @@ -60,3 +60,6 @@ issues: - bodyclose - goconst - scopelint # https://github.com/kyoh86/scopelint/issues/4 + - path: server/webhook.go + linters: + - goconst diff --git a/server/api.go b/server/api.go index ce6afacea..6b536c8da 100644 --- a/server/api.go +++ b/server/api.go @@ -417,8 +417,6 @@ func (p *Plugin) getMentions(w http.ResponseWriter, r *http.Request, userID stri } func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID string) { - ctx := context.Background() - info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { writeAPIError(w, apiErr) @@ -427,7 +425,7 @@ func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID strin githubClient := p.githubConnect(*info.Token) - notifications, _, err := githubClient.Activity.ListNotifications(ctx, &github.NotificationListOptions{}) + notifications, _, err := githubClient.Activity.ListNotifications(context.Background(), &github.NotificationListOptions{}) if err != nil { mlog.Error(err.Error()) return @@ -441,7 +439,7 @@ func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID strin filteredNotifications := []*filteredNotification{} for _, n := range notifications { - if n.GetReason() == "subscribed" { + if n.GetReason() == notificationReasonSubscribed { continue } diff --git a/server/command.go b/server/command.go index 3448eaa62..26d617a1a 100644 --- a/server/command.go +++ b/server/command.go @@ -37,9 +37,14 @@ const commandHelp = `* |/github connect [private]| - Connect your Mattermost acc * |setting| can be "notifications" or "reminders" * |value| can be "on" or "off"` +const ( + featureIssues = "issues" + featurePulls = "pulls" +) + var validFeatures = map[string]bool{ - "issues": true, - "pulls": true, + featureIssues: true, + featurePulls: true, "pushes": true, "creates": true, "deletes": true, @@ -67,7 +72,7 @@ func validateFeatures(features []string) (bool, []string) { if valid && hasLabel { // must have "pulls" or "issues" in features when using a label for _, f := range features { - if f == "pulls" || f == "issues" { + if f == featurePulls || f == featureIssues { return valid, invalidFeatures } } @@ -101,7 +106,6 @@ func (p *Plugin) getGithubClient(userInfo *GitHubUserInfo) *github.Client { } func (p *Plugin) handleSubscribe(_ *plugin.Context, args *model.CommandArgs, parameters []string, userInfo *GitHubUserInfo) string { - config := p.getConfiguration() features := "pulls,issues,creates,deletes" flags := SubscriptionFlags{} @@ -159,7 +163,7 @@ func (p *Plugin) handleSubscribe(_ *plugin.Context, args *model.CommandArgs, par ctx := context.Background() githubClient := p.getGithubClient(userInfo) - owner, repo := parseOwnerAndRepo(parameters[0], config.EnterpriseBaseURL) + owner, repo := parseOwnerAndRepo(parameters[0], p.getBaseURL()) if repo == "" { if err := p.SubscribeOrg(ctx, githubClient, args.UserId, owner, args.ChannelId, features, flags); err != nil { return err.Error() @@ -193,10 +197,9 @@ func (p *Plugin) handleDisconnect(_ *plugin.Context, args *model.CommandArgs, _ return "Disconnected your GitHub account." } func (p *Plugin) handleTodo(_ *plugin.Context, _ *model.CommandArgs, _ []string, userInfo *GitHubUserInfo) string { - ctx := context.Background() githubClient := p.getGithubClient(userInfo) - text, err := p.GetToDo(ctx, userInfo.GitHubUsername, githubClient) + text, err := p.GetToDo(context.Background(), userInfo.GitHubUsername, githubClient) if err != nil { mlog.Error(err.Error()) return "Encountered an error getting your to do items." @@ -204,9 +207,8 @@ func (p *Plugin) handleTodo(_ *plugin.Context, _ *model.CommandArgs, _ []string, return text } func (p *Plugin) handleMe(_ *plugin.Context, _ *model.CommandArgs, _ []string, userInfo *GitHubUserInfo) string { - ctx := context.Background() githubClient := p.getGithubClient(userInfo) - gitUser, _, err := githubClient.Users.Get(ctx, "") + gitUser, _, err := githubClient.Users.Get(context.Background(), "") if err != nil { return "Encountered an error getting your GitHub profile." } diff --git a/server/plugin.go b/server/plugin.go index a4cbc4603..4fd7ec38b 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -28,14 +28,18 @@ const ( githubTokenKey = "_githubtoken" githubUsernameKey = "_githubusername" githubPrivateRepoKey = "_githubprivate" - wsEventConnect = "connect" - wsEventDisconnect = "disconnect" - wsEventRefresh = "refresh" + + wsEventConnect = "connect" + wsEventDisconnect = "disconnect" + wsEventRefresh = "refresh" + settingButtonsTeam = "team" settingNotifications = "notifications" settingReminders = "reminders" settingOn = "on" settingOff = "off" + + notificationReasonSubscribed = "subscribed" ) type Plugin struct { @@ -80,9 +84,8 @@ func NewPlugin() *Plugin { func (p *Plugin) githubConnect(token oauth2.Token) *github.Client { config := p.getConfiguration() - ctx := context.Background() ts := oauth2.StaticTokenSource(&token) - tc := oauth2.NewClient(ctx, ts) + tc := oauth2.NewClient(context.Background(), ts) if len(config.EnterpriseBaseURL) == 0 || len(config.EnterpriseUploadURL) == 0 { return github.NewClient(tc) @@ -171,12 +174,9 @@ func (p *Plugin) MessageWillBePosted(c *plugin.Context, post *model.Post) (*mode func (p *Plugin) getOAuthConfig(privateAllowed bool) *oauth2.Config { config := p.getConfiguration() - authURL, _ := url.Parse("https://github.com/") - tokenURL, _ := url.Parse("https://github.com/") - if len(config.EnterpriseBaseURL) > 0 { - authURL, _ = url.Parse(config.EnterpriseBaseURL) - tokenURL, _ = url.Parse(config.EnterpriseBaseURL) - } + baseURL := p.getBaseURL() + authURL, _ := url.Parse(baseURL) + tokenURL, _ := url.Parse(baseURL) authURL.Path = path.Join(authURL.Path, "login", "oauth", "authorize") tokenURL.Path = path.Join(tokenURL.Path, "login", "oauth", "access_token") @@ -334,6 +334,7 @@ func (p *Plugin) PostToDo(info *GitHubUserInfo) { func (p *Plugin) GetToDo(ctx context.Context, username string, githubClient *github.Client) (string, error) { config := p.getConfiguration() + baseURL := p.getBaseURL() issueResults, _, err := githubClient.Search.Issues(ctx, getReviewSearchQuery(username, config.GitHubOrg), &github.SearchOptions{}) if err != nil { @@ -360,7 +361,7 @@ func (p *Plugin) GetToDo(ctx context.Context, username string, githubClient *git notificationCount := 0 notificationContent := "" for _, n := range notifications { - if n.GetReason() == "subscribed" { + if n.GetReason() == notificationReasonSubscribed { continue } @@ -382,7 +383,7 @@ func (p *Plugin) GetToDo(ctx context.Context, username string, githubClient *git default: notificationTitle := notificationSubject.GetTitle() notificationURL := fixGithubNotificationSubjectURL(notificationSubject.GetURL()) - notificationContent += getToDoDisplayText(notificationTitle, notificationURL, notificationType) + notificationContent += getToDoDisplayText(baseURL, notificationTitle, notificationURL, notificationType) } notificationCount++ @@ -403,7 +404,7 @@ func (p *Plugin) GetToDo(ctx context.Context, username string, githubClient *git text += fmt.Sprintf("You have %v pull requests awaiting your review:\n", issueResults.GetTotal()) for _, pr := range issueResults.Issues { - text += getToDoDisplayText(pr.GetTitle(), pr.GetHTMLURL(), "") + text += getToDoDisplayText(baseURL, pr.GetTitle(), pr.GetHTMLURL(), "") } } @@ -415,7 +416,7 @@ func (p *Plugin) GetToDo(ctx context.Context, username string, githubClient *git text += fmt.Sprintf("You have %v open pull requests:\n", yourPrs.GetTotal()) for _, pr := range yourPrs.Issues { - text += getToDoDisplayText(pr.GetTitle(), pr.GetHTMLURL(), "") + text += getToDoDisplayText(baseURL, pr.GetTitle(), pr.GetHTMLURL(), "") } } @@ -427,7 +428,7 @@ func (p *Plugin) GetToDo(ctx context.Context, username string, githubClient *git text += fmt.Sprintf("You have %v assignments:\n", yourAssignments.GetTotal()) for _, assign := range yourAssignments.Issues { - text += getToDoDisplayText(assign.GetTitle(), assign.GetHTMLURL(), "") + text += getToDoDisplayText(baseURL, assign.GetTitle(), assign.GetHTMLURL(), "") } } @@ -466,7 +467,7 @@ func (p *Plugin) HasUnreads(info *GitHubUserInfo) bool { } for _, n := range notifications { - if n.GetReason() == "subscribed" { + if n.GetReason() == notificationReasonSubscribed { continue } @@ -522,3 +523,12 @@ func (p *Plugin) sendRefreshEvent(userID string) { &model.WebsocketBroadcast{UserId: userID}, ) } + +func (p *Plugin) getBaseURL() string { + config := p.getConfiguration() + if config.EnterpriseBaseURL != "" { + return config.EnterpriseBaseURL + } + + return "https://github.com/" +} diff --git a/server/subscriptions.go b/server/subscriptions.go index 2ad15cd79..c94d6745e 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -53,11 +53,11 @@ type Subscriptions struct { } func (s *Subscription) Pulls() bool { - return strings.Contains(s.Features, "pulls") + return strings.Contains(s.Features, featurePulls) } func (s *Subscription) Issues() bool { - return strings.Contains(s.Features, "issues") + return strings.Contains(s.Features, featureIssues) } func (s *Subscription) Pushes() bool { @@ -278,9 +278,7 @@ func (p *Plugin) GetSubscribedChannelsForRepository(repo *github.Repository) []* } func (p *Plugin) Unsubscribe(channelID string, repo string) error { - config := p.getConfiguration() - - owner, repo := parseOwnerAndRepo(repo, config.EnterpriseBaseURL) + owner, repo := parseOwnerAndRepo(repo, p.getBaseURL()) if owner == "" && repo == "" { return fmt.Errorf("envalid repository") } diff --git a/server/utils.go b/server/utils.go index 1517ec9f5..9fcab0289 100644 --- a/server/utils.go +++ b/server/utils.go @@ -117,9 +117,6 @@ func decrypt(key []byte, text string) (string, error) { } func parseOwnerAndRepo(full, baseURL string) (string, string) { - if baseURL == "" { - baseURL = "https://github.com/" - } full = strings.TrimSuffix(strings.TrimSpace(strings.Replace(full, baseURL, "", 1)), "/") splitStr := strings.Split(full, "/") @@ -310,9 +307,7 @@ func getCodeMarkdown(user, repo, repoPath, word, lines string, isTruncated bool) } // getToDoDisplayText returns the text to be displayed in todo listings. -func getToDoDisplayText(title, url, notifType string) string { - baseURL := "https://github.com/" - +func getToDoDisplayText(baseURL, title, url, notifType string) string { owner, repo := parseOwnerAndRepo(url, baseURL) repoURL := fmt.Sprintf("%s%s/%s", baseURL, owner, repo) repoWords := strings.Split(repo, "-") diff --git a/server/utils_test.go b/server/utils_test.go index b4e6d997c..be3421c16 100644 --- a/server/utils_test.go +++ b/server/utils_test.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -60,22 +61,24 @@ func TestParseOwnerAndRepo(t *testing.T) { }{ {Full: "mattermost", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: ""}, {Full: "mattermost", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: ""}, - {Full: "https://github.com/mattermost", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: ""}, + {Full: "https://example.org/mattermost", BaseURL: "https://example.org/", ExpectedOwner: "mattermost", ExpectedRepo: ""}, {Full: "https://github.com/mattermost", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: ""}, {Full: "mattermost/mattermost-server", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"}, {Full: "mattermost/mattermost-server", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"}, - {Full: "https://github.com/mattermost/mattermost-server", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"}, + {Full: "https://example.org/mattermost/mattermost-server", BaseURL: "https://example.org/", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"}, {Full: "https://github.com/mattermost/mattermost-server", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"}, {Full: "", BaseURL: "", ExpectedOwner: "", ExpectedRepo: ""}, {Full: "mattermost/mattermost/invalid_repo_url", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost"}, - {Full: "https://github.com/mattermost/mattermost/invalid_repo_url", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost"}, + {Full: "https://github.com/mattermost/mattermost/invalid_repo_url", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost"}, } - for _, tc := range tcs { - owner, repo := parseOwnerAndRepo(tc.Full, tc.BaseURL) + for i, tc := range tcs { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + owner, repo := parseOwnerAndRepo(tc.Full, tc.BaseURL) - assert.Equal(t, owner, tc.ExpectedOwner) - assert.Equal(t, repo, tc.ExpectedRepo) + assert.Equal(t, tc.ExpectedOwner, owner) + assert.Equal(t, tc.ExpectedRepo, repo) + }) } } @@ -244,7 +247,7 @@ func TestGetToDoDisplayText(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got := getToDoDisplayText(tc.in.title, tc.in.url, tc.in.notifType) + got := getToDoDisplayText("https://github.com/", tc.in.title, tc.in.url, tc.in.notifType) assert.Equal(t, tc.want, got) }) } diff --git a/server/webhook.go b/server/webhook.go index 375bcae79..49071eacf 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -136,9 +136,7 @@ func (p *Plugin) permissionToRepo(userID string, ownerAndRepo string) bool { return false } - config := p.getConfiguration() - ctx := context.Background() - owner, repo := parseOwnerAndRepo(ownerAndRepo, config.EnterpriseBaseURL) + owner, repo := parseOwnerAndRepo(ownerAndRepo, p.getBaseURL()) if owner == "" { return false @@ -153,7 +151,7 @@ func (p *Plugin) permissionToRepo(userID string, ownerAndRepo string) bool { } githubClient := p.githubConnect(*info.Token) - if result, _, err := githubClient.Repositories.Get(ctx, owner, repo); result == nil || err != nil { + if result, _, err := githubClient.Repositories.Get(context.Background(), owner, repo); result == nil || err != nil { if err != nil { mlog.Error(err.Error()) } From fd36a1ce1a70cca478beba28f09336ac172df276 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 19:57:33 +0200 Subject: [PATCH 05/16] Enable errcheck --- .golangci.yml | 2 +- server/api.go | 180 ++++++++++++++++++++--------------- server/api_test.go | 2 +- server/plugin.go | 53 +++++++---- server/subscriptions.go | 26 +++-- server/subscriptions_test.go | 2 +- server/webhook.go | 35 +++++-- 7 files changed, 188 insertions(+), 112 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index abec547a0..4d5e63df1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,7 +23,7 @@ linters: enable: - bodyclose - deadcode - #- errcheck + - errcheck - goconst - gocritic - gofmt diff --git a/server/api.go b/server/api.go index 6b536c8da..2138a2067 100644 --- a/server/api.go +++ b/server/api.go @@ -48,13 +48,40 @@ type PRDetails struct { type HTTPHandlerFuncWithUser func(w http.ResponseWriter, r *http.Request, userID string) -func writeAPIError(w http.ResponseWriter, err *APIErrorResponse) { - b, _ := json.Marshal(err) - w.WriteHeader(err.StatusCode) - w.Write(b) +func (p *Plugin) writeJSON(w http.ResponseWriter, v interface{}) { + b, err := json.Marshal(v) + if err != nil { + p.API.LogWarn("Failed to marshal JSON response", "error", err.Error()) + w.WriteHeader(http.StatusInternalServerError) + return + } + _, err = w.Write(b) + if err != nil { + p.API.LogWarn("Failed to write JSON response", "error", err.Error()) + w.WriteHeader(http.StatusInternalServerError) + return + } } -func (p *Plugin) initialiseAPI() { +func (p *Plugin) writeAPIError(w http.ResponseWriter, apiErr *APIErrorResponse) { + b, err := json.Marshal(apiErr) + if err != nil { + p.API.LogWarn("Failed to marshal API error", "error", err.Error()) + w.WriteHeader(http.StatusInternalServerError) + return + } + + w.WriteHeader(apiErr.StatusCode) + + _, err = w.Write(b) + if err != nil { + p.API.LogWarn("Failed to write JSON response", "error", err.Error()) + w.WriteHeader(http.StatusInternalServerError) + return + } +} + +func (p *Plugin) initializeAPI() { p.router = mux.NewRouter() oauthRouter := p.router.PathPrefix("/oauth").Subrouter() @@ -84,7 +111,7 @@ func (p *Plugin) extractUserMiddleWare(handler HTTPHandlerFuncWithUser, jsonResp userID := r.Header.Get("Mattermost-User-ID") if userID == "" { if jsonResponse { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Not authorized.", StatusCode: http.StatusUnauthorized}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Not authorized.", StatusCode: http.StatusUnauthorized}) } else { http.Error(w, "Not authorized", http.StatusUnauthorized) } @@ -209,13 +236,13 @@ func (p *Plugin) completeConnectUserToGitHub(w http.ResponseWriter, r *http.Requ AllowedPrivateRepos: state.PrivateAllowed, } - if err := p.storeGitHubUserInfo(userInfo); err != nil { + if err = p.storeGitHubUserInfo(userInfo); err != nil { fmt.Println(err.Error()) http.Error(w, "Unable to connect user to GitHub", http.StatusInternalServerError) return } - if err := p.storeGitHubToUserIDMapping(gitUser.GetLogin(), state.UserID); err != nil { + if err = p.storeGitHubToUserIDMapping(gitUser.GetLogin(), state.UserID); err != nil { fmt.Println(err.Error()) } @@ -269,7 +296,12 @@ func (p *Plugin) completeConnectUserToGitHub(w http.ResponseWriter, r *http.Requ ` w.Header().Set("Content-Type", "text/html") - w.Write([]byte(html)) + _, err = w.Write([]byte(html)) + if err != nil { + p.API.LogWarn("Failed to write HTML response", "error", err.Error()) + w.WriteHeader(http.StatusInternalServerError) + return + } } type ConnectedResponse struct { @@ -301,39 +333,34 @@ type GitHubUserResponse struct { func (p *Plugin) getGitHubUser(w http.ResponseWriter, r *http.Request, _ string) { req := &GitHubUserRequest{} if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - mlog.Error("Error decoding JSON body", mlog.Err(err)) - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) + mlog.Error("Error decoding GitHubUserRequest from JSON body", mlog.Err(err)) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) return } if req.UserID == "" { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object with a non-blank user_id field.", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object with a non-blank user_id field.", StatusCode: http.StatusBadRequest}) return } userInfo, apiErr := p.getGitHubUserInfo(req.UserID) if apiErr != nil { if apiErr.ID == apiErrorIDNotConnected { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "User is not connected to a GitHub account.", StatusCode: http.StatusNotFound}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "User is not connected to a GitHub account.", StatusCode: http.StatusNotFound}) } else { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) } return } if userInfo == nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "User is not connected to a GitHub account.", StatusCode: http.StatusNotFound}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "User is not connected to a GitHub account.", StatusCode: http.StatusNotFound}) return } resp := &GitHubUserResponse{Username: userInfo.GitHubUsername} - b, err := json.Marshal(resp) - if err != nil { - mlog.Error("Error encoding JSON response: " + err.Error()) - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an unexpected error. Please try again.", StatusCode: http.StatusInternalServerError}) - return - } - w.Write(b) + + p.writeJSON(w, resp) } func (p *Plugin) getConnected(w http.ResponseWriter, r *http.Request, userID string) { @@ -367,7 +394,9 @@ func (p *Plugin) getConnected(w http.ResponseWriter, r *http.Request, userID str if p.HasUnreads(info) { p.PostToDo(info) info.LastToDoPostAt = now - p.storeGitHubUserInfo(info) + if err := p.storeGitHubUserInfo(info); err != nil { + p.API.LogWarn("Failed to store github info for new user", "userID", userID, "error", err.Error()) + } } } } @@ -390,8 +419,7 @@ func (p *Plugin) getConnected(w http.ResponseWriter, r *http.Request, userID str } } - b, _ := json.Marshal(resp) - w.Write(b) + p.writeJSON(w, resp) } func (p *Plugin) getMentions(w http.ResponseWriter, r *http.Request, userID string) { @@ -399,7 +427,7 @@ func (p *Plugin) getMentions(w http.ResponseWriter, r *http.Request, userID stri info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -412,14 +440,13 @@ func (p *Plugin) getMentions(w http.ResponseWriter, r *http.Request, userID stri return } - resp, _ := json.Marshal(result.Issues) - w.Write(resp) + p.writeJSON(w, result.Issues) } func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID string) { info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -453,8 +480,7 @@ func (p *Plugin) getUnreads(w http.ResponseWriter, r *http.Request, userID strin }) } - resp, _ := json.Marshal(filteredNotifications) - w.Write(resp) + p.writeJSON(w, filteredNotifications) } func (p *Plugin) getReviews(w http.ResponseWriter, r *http.Request, userID string) { @@ -462,7 +488,7 @@ func (p *Plugin) getReviews(w http.ResponseWriter, r *http.Request, userID strin info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -475,8 +501,7 @@ func (p *Plugin) getReviews(w http.ResponseWriter, r *http.Request, userID strin return } - resp, _ := json.Marshal(result.Issues) - w.Write(resp) + p.writeJSON(w, result.Issues) } func (p *Plugin) getYourPrs(w http.ResponseWriter, r *http.Request, userID string) { @@ -484,7 +509,7 @@ func (p *Plugin) getYourPrs(w http.ResponseWriter, r *http.Request, userID strin info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -497,21 +522,24 @@ func (p *Plugin) getYourPrs(w http.ResponseWriter, r *http.Request, userID strin return } - resp, _ := json.Marshal(result.Issues) - w.Write(resp) + p.writeJSON(w, result.Issues) } func (p *Plugin) getPrsDetails(w http.ResponseWriter, r *http.Request, userID string) { info, err := p.getGitHubUserInfo(userID) if err != nil { - writeAPIError(w, err) + p.writeAPIError(w, err) return } githubClient := p.githubConnect(*info.Token) var prList []*PRDetails - json.NewDecoder(r.Body).Decode(&prList) + if err := json.NewDecoder(r.Body).Decode(&prList); err != nil { + mlog.Error("Error decoding PRDetails JSON body", mlog.Err(err)) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) + return + } prDetails := make([]*PRDetails, len(prList)) ctx := context.Background() @@ -529,8 +557,7 @@ func (p *Plugin) getPrsDetails(w http.ResponseWriter, r *http.Request, userID st wg.Wait() - resp, _ := json.Marshal(prDetails) - w.Write(resp) + p.writeJSON(w, prDetails) } func fetchPRDetails(ctx context.Context, client *github.Client, prURL string, prNumber int) *PRDetails { @@ -605,7 +632,7 @@ func (p *Plugin) searchIssues(w http.ResponseWriter, r *http.Request, userID str info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -619,8 +646,7 @@ func (p *Plugin) searchIssues(w http.ResponseWriter, r *http.Request, userID str return } - resp, _ := json.Marshal(result.Issues) - w.Write(resp) + p.writeJSON(w, result.Issues) } func getPermaLink(siteURL string, postID string, currentTeam string) string { @@ -649,44 +675,44 @@ func getFailReason(code int, repo string, username string) string { func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, userID string) { req := &CreateIssueCommentRequest{} if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - mlog.Error("Error decoding JSON body", mlog.Err(err)) - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) + mlog.Error("Error decoding CreateIssueCommentRequest JSON body", mlog.Err(err)) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a JSON object.", StatusCode: http.StatusBadRequest}) return } if req.PostID == "" { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid post id", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid post id", StatusCode: http.StatusBadRequest}) return } if req.Owner == "" { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid repo owner.", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid repo owner.", StatusCode: http.StatusBadRequest}) return } if req.Repo == "" { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid repo.", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid repo.", StatusCode: http.StatusBadRequest}) return } if req.Number == 0 { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid issue number.", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid issue number.", StatusCode: http.StatusBadRequest}) return } if req.Comment == "" { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid non empty comment.", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid non empty comment.", StatusCode: http.StatusBadRequest}) return } if req.CurrentTeam == "" { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid team", StatusCode: http.StatusBadRequest}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Please provide a valid team", StatusCode: http.StatusBadRequest}) return } info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -694,23 +720,23 @@ func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, user post, appErr := p.API.GetPost(req.PostID) if appErr != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostID, StatusCode: http.StatusInternalServerError}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostID, StatusCode: http.StatusInternalServerError}) return } if post == nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostID + ": not found", StatusCode: http.StatusNotFound}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post " + req.PostID + ": not found", StatusCode: http.StatusNotFound}) return } commentUser, appErr := p.API.GetUser(post.UserId) if appErr != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post.UserID " + post.UserId + ": not found", StatusCode: http.StatusInternalServerError}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load post.UserID " + post.UserId + ": not found", StatusCode: http.StatusInternalServerError}) return } currentUser, appErr := p.API.GetUser(userID) if appErr != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load current user", StatusCode: http.StatusInternalServerError}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to load current user", StatusCode: http.StatusInternalServerError}) return } @@ -726,7 +752,7 @@ func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, user result, rawResponse, err := githubClient.Issues.CreateComment(context.Background(), req.Owner, req.Repo, req.Number, comment) if err != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create an issue comment: " + getFailReason(rawResponse.StatusCode, req.Repo, currentUser.Username), StatusCode: rawResponse.StatusCode}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create an issue comment: " + getFailReason(rawResponse.StatusCode, req.Repo, currentUser.Username), StatusCode: rawResponse.StatusCode}) return } rootID := req.PostID @@ -745,11 +771,11 @@ func (p *Plugin) createIssueComment(w http.ResponseWriter, r *http.Request, user _, appErr = p.API.CreatePost(reply) if appErr != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create notification post " + req.PostID, StatusCode: http.StatusInternalServerError}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create notification post " + req.PostID, StatusCode: http.StatusInternalServerError}) return } - resp, _ := json.Marshal(result) - w.Write(resp) + + p.writeJSON(w, result) } func (p *Plugin) getYourAssignments(w http.ResponseWriter, r *http.Request, userID string) { @@ -757,7 +783,7 @@ func (p *Plugin) getYourAssignments(w http.ResponseWriter, r *http.Request, user info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -770,14 +796,13 @@ func (p *Plugin) getYourAssignments(w http.ResponseWriter, r *http.Request, user return } - resp, _ := json.Marshal(result.Issues) - w.Write(resp) + p.writeJSON(w, result.Issues) } func (p *Plugin) postToDo(w http.ResponseWriter, r *http.Request, userID string) { info, apiErr := p.getGitHubUserInfo(userID) if apiErr != nil { - writeAPIError(w, apiErr) + p.writeAPIError(w, apiErr) return } @@ -787,21 +812,27 @@ func (p *Plugin) postToDo(w http.ResponseWriter, r *http.Request, userID string) text, err := p.GetToDo(context.Background(), username, githubClient) if err != nil { mlog.Error(err.Error()) - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an error getting the to do items.", StatusCode: http.StatusUnauthorized}) + p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an error getting the to do items.", StatusCode: http.StatusUnauthorized}) return } - if err := p.CreateBotDMPost(userID, text, "custom_git_todo"); err != nil { - writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an error posting the to do items.", StatusCode: http.StatusUnauthorized}) - return - } + p.CreateBotDMPost(userID, text, "custom_git_todo") + + resp := struct { + Status string + }{"OK"} - w.Write([]byte("{\"status\": \"OK\"}")) + p.writeJSON(w, resp) } func (p *Plugin) updateSettings(w http.ResponseWriter, r *http.Request, userID string) { var settings *UserSettings - json.NewDecoder(r.Body).Decode(&settings) + if err := json.NewDecoder(r.Body).Decode(&settings); err != nil { + mlog.Error("Error decoding settings from JSON body", mlog.Err(err)) + http.Error(w, "Invalid request body", http.StatusBadRequest) + return + } + if settings == nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return @@ -809,7 +840,7 @@ func (p *Plugin) updateSettings(w http.ResponseWriter, r *http.Request, userID s info, err := p.getGitHubUserInfo(userID) if err != nil { - writeAPIError(w, err) + p.writeAPIError(w, err) return } @@ -821,6 +852,5 @@ func (p *Plugin) updateSettings(w http.ResponseWriter, r *http.Request, userID s return } - resp, _ := json.Marshal(info.Settings) - w.Write(resp) + p.writeJSON(w, info.Settings) } diff --git a/server/api_test.go b/server/api_test.go index c53cf25da..92c13aea7 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -72,7 +72,7 @@ func TestPlugin_ServeHTTP(t *testing.T) { EnterpriseUploadURL: "", EnableCodePreview: false, }) - p.initialiseAPI() + p.initializeAPI() req := tt.httpTest.CreateHTTPRequest(tt.request) req.Header.Add("Mattermost-User-ID", tt.userID) diff --git a/server/plugin.go b/server/plugin.go index 4fd7ec38b..2691e7b47 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -112,9 +112,11 @@ func (p *Plugin) OnActivate() error { return err } - p.initialiseAPI() + p.initializeAPI() - p.API.RegisterCommand(getCommand()) + if err := p.API.RegisterCommand(getCommand()); err != nil { + return err + } botID, err := p.Helpers.EnsureBot(&model.Bot{ Username: "github", @@ -240,9 +242,12 @@ func (p *Plugin) getGitHubUserInfo(userID string) (*GitHubUserInfo, *APIErrorRes var userInfo GitHubUserInfo - if infoBytes, err := p.API.KVGet(userID + githubTokenKey); err != nil || infoBytes == nil { + infoBytes, appErr := p.API.KVGet(userID + githubTokenKey) + if appErr != nil || infoBytes == nil { return nil, &APIErrorResponse{ID: apiErrorIDNotConnected, Message: "Must connect user account to GitHub first.", StatusCode: http.StatusBadRequest} - } else if err := json.Unmarshal(infoBytes, &userInfo); err != nil { + } + + if err := json.Unmarshal(infoBytes, &userInfo); err != nil { return nil, &APIErrorResponse{ID: "", Message: "Unable to parse token.", StatusCode: http.StatusInternalServerError} } @@ -285,12 +290,26 @@ func (p *Plugin) disconnectGitHubAccount(userID string) { return } - p.API.KVDelete(userID + githubTokenKey) - p.API.KVDelete(userInfo.GitHubUsername + githubUsernameKey) + if err := p.API.KVDelete(userID + githubTokenKey); err != nil { + p.API.LogWarn("Failed to delete github token", "userID", userID, "error", err.Error()) + } - if user, err := p.API.GetUser(userID); err == nil && user.Props != nil && len(user.Props["git_user"]) > 0 { - delete(user.Props, "git_user") - p.API.UpdateUser(user) + if err := p.API.KVDelete(userInfo.GitHubUsername + githubUsernameKey); err != nil { + p.API.LogWarn("Failed to delete github token", "userID", userID, "error", err.Error()) + } + + user, err := p.API.GetUser(userID) + if err != nil { + p.API.LogWarn("Failed to get user props", "userID", userID, "error", err.Error()) + } else { + _, ok := user.Props["git_user"] + if ok { + delete(user.Props, "git_user") + _, err := p.API.UpdateUser(user) + if err != nil { + p.API.LogWarn("Failed to get update user props", "userID", userID, "error", err.Error()) + } + } } p.API.PublishWebSocketEvent( @@ -300,11 +319,13 @@ func (p *Plugin) disconnectGitHubAccount(userID string) { ) } -func (p *Plugin) CreateBotDMPost(userID, message, postType string) *model.AppError { +// CreateBotDMPost posts a direct message using the bot account. +// Any error are not returned and instead logged. +func (p *Plugin) CreateBotDMPost(userID, message, postType string) { channel, err := p.API.GetDirectChannel(userID, p.BotUserID) if err != nil { - mlog.Error("Couldn't get bot's DM channel", mlog.String("user_id", userID)) - return err + p.API.LogWarn("Couldn't get bot's DM channel", "userID", userID, "error", err.Error()) + return } post := &model.Post{ @@ -315,17 +336,15 @@ func (p *Plugin) CreateBotDMPost(userID, message, postType string) *model.AppErr } if _, err := p.API.CreatePost(post); err != nil { - mlog.Error(err.Error()) - return err + p.API.LogWarn("Failed to create DM post", "userID", userID, "error", err.Error()) + return } - - return nil } func (p *Plugin) PostToDo(info *GitHubUserInfo) { text, err := p.GetToDo(context.Background(), info.GitHubUsername, p.githubConnect(*info.Token)) if err != nil { - mlog.Error(err.Error()) + p.API.LogWarn("Failed to get todo text", "userID", info.UserID, "error", err.Error()) return } diff --git a/server/subscriptions.go b/server/subscriptions.go index c94d6745e..7674800e4 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -14,7 +14,7 @@ import ( ) const ( - subcriptionsKey = "subscriptions" + SubscriptionsKey = "subscriptions" excludeOrgMemberFlag = "exclude-org-member" ) @@ -218,15 +218,18 @@ func (p *Plugin) AddSubscription(repo string, sub *Subscription) error { func (p *Plugin) GetSubscriptions() (*Subscriptions, error) { var subscriptions *Subscriptions - value, err := p.API.KVGet(subcriptionsKey) - if err != nil { - return nil, err + value, appErr := p.API.KVGet(SubscriptionsKey) + if appErr != nil { + return nil, appErr } if value == nil { - subscriptions = &Subscriptions{Repositories: map[string][]*Subscription{}} - } else { - json.NewDecoder(bytes.NewReader(value)).Decode(&subscriptions) + return &Subscriptions{Repositories: map[string][]*Subscription{}}, nil + } + + err := json.NewDecoder(bytes.NewReader(value)).Decode(&subscriptions) + if err != nil { + return nil, err } return subscriptions, nil @@ -237,7 +240,12 @@ func (p *Plugin) StoreSubscriptions(s *Subscriptions) error { if err != nil { return err } - p.API.KVSet(subcriptionsKey, b) + + appErr := p.API.KVSet(SubscriptionsKey, b) + if appErr != nil { + return appErr + } + return nil } @@ -280,7 +288,7 @@ func (p *Plugin) GetSubscribedChannelsForRepository(repo *github.Repository) []* func (p *Plugin) Unsubscribe(channelID string, repo string) error { owner, repo := parseOwnerAndRepo(repo, p.getBaseURL()) if owner == "" && repo == "" { - return fmt.Errorf("envalid repository") + return fmt.Errorf("invalid repository") } repoWithOwner := fmt.Sprintf("%s/%s", owner, repo) diff --git a/server/subscriptions_test.go b/server/subscriptions_test.go index b7162c3ed..094d99d50 100644 --- a/server/subscriptions_test.go +++ b/server/subscriptions_test.go @@ -24,7 +24,7 @@ func pluginWithMockedSubs(subscriptions []*Subscription) *Plugin { subs := Subscriptions{Repositories: map[string][]*Subscription{}} subs.Repositories[""] = subscriptions jsn, _ := json.Marshal(subs) - mockPluginAPI.On("KVGet", subcriptionsKey).Return(jsn, nil) + mockPluginAPI.On("KVGet", SubscriptionsKey).Return(jsn, nil) p.SetAPI(mockPluginAPI) return p } diff --git a/server/webhook.go b/server/webhook.go index 49071eacf..93de94c1d 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -16,24 +16,36 @@ import ( "github.com/google/go-github/v25/github" ) -func verifyWebhookSignature(secret []byte, signature string, body []byte) bool { +func verifyWebhookSignature(secret []byte, signature string, body []byte) (bool, error) { const signaturePrefix = "sha1=" const signatureLength = 45 if len(signature) != signatureLength || !strings.HasPrefix(signature, signaturePrefix) { - return false + return false, nil } actual := make([]byte, 20) - hex.Decode(actual, []byte(signature[5:])) + _, err := hex.Decode(actual, []byte(signature[5:])) + if err != nil { + return false, err + } - return hmac.Equal(signBody(secret, body), actual) + sb, err := signBody(secret, body) + if err != nil { + return false, err + } + + return hmac.Equal(sb, actual), nil } -func signBody(secret, body []byte) []byte { +func signBody(secret, body []byte) ([]byte, error) { computed := hmac.New(sha1.New, secret) - computed.Write(body) - return computed.Sum(nil) + _, err := computed.Write(body) + if err != nil { + return nil, err + } + + return computed.Sum(nil), nil } // Hack to convert from github.PushEventRepository to github.Repository @@ -57,7 +69,14 @@ func (p *Plugin) handleWebhook(w http.ResponseWriter, r *http.Request) { return } - if !verifyWebhookSignature([]byte(config.WebhookSecret), signature, body) { + valid, err := verifyWebhookSignature([]byte(config.WebhookSecret), signature, body) + if err != nil { + p.API.LogWarn("Failed to verify webhook signature", "error", err.Error()) + http.Error(w, "", http.StatusInternalServerError) + return + } + + if !valid { http.Error(w, "Not authorized", http.StatusUnauthorized) return } From 6b3bcf1cd5306551bce8d26e14581cada1018e2a Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 20:06:30 +0200 Subject: [PATCH 06/16] Update dependencies --- go.mod | 10 +- go.sum | 273 +++++++++++++++++++++++++++----------- server/api.go | 2 +- server/command.go | 2 +- server/permalinks.go | 2 +- server/permalinks_test.go | 2 +- server/plugin.go | 2 +- server/subscriptions.go | 2 +- server/template_test.go | 10 +- server/webhook.go | 2 +- 10 files changed, 209 insertions(+), 98 deletions(-) diff --git a/go.mod b/go.mod index b6ee8ef92..ba94e022d 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module github.com/mattermost/mattermost-plugin-github go 1.12 require ( - github.com/Masterminds/sprig/v3 v3.0.2 - github.com/google/go-github/v25 v25.1.1 + github.com/Masterminds/sprig/v3 v3.1.0 + github.com/google/go-github/v31 v31.0.0 github.com/gorilla/mux v1.7.4 - github.com/mattermost/mattermost-server/v5 v5.18.0 + github.com/mattermost/mattermost-server/v5 v5.22.0 github.com/mholt/archiver/v3 v3.3.0 - github.com/pkg/errors v0.8.1 - github.com/stretchr/testify v1.4.0 + github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.5.1 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 ) diff --git a/go.sum b/go.sum index e7de19fda..9ada7ffd8 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,35 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.37.1/go.mod h1:SAbnLi6YTSPKSI0dTUEOVLCkyPfKXK8n4ibqiMoj4ok= contrib.go.opencensus.io/exporter/ocagent v0.4.9/go.mod h1:ueLzZcP7LPhPulEBukGn4aLh7Mx9YJwpVJ9nL2FYltw= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/Azure/azure-sdk-for-go v26.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v11.5.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.0.2 h1:wz22D0CiSctrliXiI9ZO3HoNApweeRGftyDN+BQa3B8= -github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU= +github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk= +github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y= +github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA= github.com/Masterminds/squirrel v1.1.0 h1:baP1qLdoQCeTw3ifCdOq2dkYc6vGcmRdaociKLbEJXs= github.com/Masterminds/squirrel v1.1.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA= github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/PaulARoy/azurestoragecache v0.0.0-20170906084534-3c249a3ba788/go.mod h1:lY1dZd8HBzJ10eqKERHn3CU59tfhzcAVb2c0ZhIWSOk= +github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91/go.mod h1:cDLGBht23g0XQdLjzn6xOGXDkLK182YfINAaZEQLCHQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -36,10 +42,11 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/avct/uasurfer v0.0.0-20190821150637-906cc7dc6197/go.mod h1:noBAuukeYOXa0aXGqxr24tADqkwDO2KRD15FsuaZ5a8= +github.com/avct/uasurfer v0.0.0-20191028135549-26b5daa857f1/go.mod h1:noBAuukeYOXa0aXGqxr24tADqkwDO2KRD15FsuaZ5a8= github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +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/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -48,10 +55,14 @@ github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdn github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -66,7 +77,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3/go.mod h1:hEfFauPHz7+NnjR/yHJGhrKo1Za+zStgwUETx3yzqgY= github.com/die-net/lrucache v0.0.0-20181227122439-19a39ef22a11/go.mod h1:ew0MSjCVDdtGMjF3kzLK9hwdgF5mOE8SbYVF3Rc7mkU= github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= -github.com/disintegration/imaging v1.6.1/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= @@ -77,15 +88,22 @@ github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYi github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-asn1-ber/asn1-ber v1.3.2-0.20191121212151-29be175fc3a3 h1:QW2p25fGTu/S0MvEftCo3wV7aEFHBt2m1DTg1HUwh+o= +github.com/go-asn1-ber/asn1-ber v1.3.2-0.20191121212151-29be175fc3a3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gorp/gorp v2.0.0+incompatible h1:dIQPsBtl6/H1MjVseWuWPXa7ET4p6Dve4j3Hg+UjqYw= github.com/go-gorp/gorp v2.0.0+incompatible/go.mod h1:7IfkAQnO7jfT/9IQ3R9wL1dFhukN6aQxzKTHnkxzA/E= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -93,8 +111,7 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -121,20 +138,25 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-github/v25 v25.1.1 h1:6eW++i/CXcR5GKfYaaJT7oJJtHNU+/iiw55noEPNVao= -github.com/google/go-github/v25 v25.1.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= +github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= +github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -154,12 +176,13 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:Fecb github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hako/durafmt v0.0.0-20190612201238-650ed9f29a84/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE= +github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE= +github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= -github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= @@ -174,7 +197,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 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.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= @@ -183,19 +206,20 @@ github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d h1:W+SIwDdl3+jXWei github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= -github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jamiealquiza/envy v1.1.0/go.mod h1:MP36BriGCLwEHhi1OU8E9569JNZrjWfCvzG7RsPnHus= github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -220,35 +244,45 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtB github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattermost/go-i18n v1.11.0 h1:1hLKqn/ZvhZ80OekjVPGYcCrBfMz+YxNNgqS+beL7zE= github.com/mattermost/go-i18n v1.11.0/go.mod h1:RyS7FDNQlzF1PsjbJWHRI35exqaKGSO9qD4iv8QjE34= github.com/mattermost/gorp v2.0.1-0.20190301154413-3b31e9a39d05+incompatible h1:FN4zK2wNig7MVVsOsGEZ+LeIq0gUcudn3LEGgbodMq8= github.com/mattermost/gorp v2.0.1-0.20190301154413-3b31e9a39d05+incompatible/go.mod h1:0kX1qa3DOpaPJyOdMLeo7TcBN0QmUszj9a/VygOhDe0= -github.com/mattermost/ldap v3.0.4+incompatible h1:SOeNnz+JNR+foQ3yHkYqijb9MLPhXN2BZP/PdX23VDU= -github.com/mattermost/ldap v3.0.4+incompatible/go.mod h1:b4reDCcGpBxJ4WX0f224KFY+OR0npin7or7EFpeIko4= -github.com/mattermost/mattermost-server/v5 v5.18.0 h1:In1v/1vrYMEDRHiXe6sA50KJ5WGkE2mLtsIz7YOGsN8= -github.com/mattermost/mattermost-server/v5 v5.18.0/go.mod h1:10vIYDohcPNDMDk3XlRUjNO9nGk9fnFHEFeSIUYR82k= +github.com/mattermost/gosaml2 v0.3.2/go.mod h1:Z429EIOiEi9kbq6yHoApfzlcXpa6dzRDc6pO+Vy2Ksk= +github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d h1:2DV7VIlEv6J5R5o6tUcb3ZMKJYeeZuWZL7Rv1m23TgQ= +github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ= +github.com/mattermost/mattermost-server/v5 v5.22.0 h1:LxRm0WUhN4nkRbwGK/TmCRW3SBDbxNPbyu/+aSswJxU= +github.com/mattermost/mattermost-server/v5 v5.22.0/go.mod h1:ML8BRTnmU/pS6gqRVWJDjl7tk5puO+bt5z1MiPuFHIA= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs= github.com/mattermost/viper v1.0.4/go.mod h1:uc5hKG9lv4/KRwPOt2c1omOyirS/UnuA2TytiZQSFHM= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mholt/archiver/v3 v3.3.0 h1:vWjhY8SQp5yzM9P6OJ/eZEkmi3UAbRrxCq48MxjAzig= github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08Ebtr1Mqao= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.19/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/minio/minio-go/v6 v6.0.40/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= +github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/minio/minio-go/v6 v6.0.45/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= @@ -269,20 +303,22 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/muesli/smartcrop v0.2.1-0.20181030220600-548bbf0c0965/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI= github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs= github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= +github.com/olivere/elastic v6.2.27+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -291,14 +327,16 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= 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= -github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/peterbourgon/diskv v0.0.0-20171120014656-2973218375c3/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -307,27 +345,28 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7/go.mod h1:Oz4y6ImuOQZxynhbSXk7btjEfNBtGlj2dcaOvXl2FSM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/rwcarlsen/goexif v0.0.0-20190318171057-76e3344f7516/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -336,17 +375,43 @@ github.com/satori/go.uuid v0.0.0-20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/analytics-go v3.1.0+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48= github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +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/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -363,13 +428,22 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/throttled/throttled v2.2.4+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLsyRdqpSRvJpq0PNIsOtqP9Nos= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II= +github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/wiggin77/cfg v1.0.2/go.mod h1:b3gotba2e5bXTqTW48DwIFoLc+4lWKP7WPi/CdvZ4aE= +github.com/wiggin77/logr v1.0.4/go.mod h1:h98FF6GPfThhDrHCg063hZA1sIyOEzQ/P85wgqI0IqE= +github.com/wiggin77/merror v1.0.2/go.mod h1:uQTcIU0Z6jRK4OwqganPYerzQxSFJ4GSHM3aurxxQpg= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -379,36 +453,49 @@ github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wK go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A= go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= -go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4= 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-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/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-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE= -golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -423,16 +510,16 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4= -golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 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= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -446,6 +533,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -459,16 +547,19 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed h1:5TJcLJn2a55mJjzYk0yOoqN8X1OdvBDUnaZaKKyQtkY= -golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 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= @@ -478,6 +569,7 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -485,54 +577,67 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191002161851-3769738f410b/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200213050514-49b8ac185c84 h1:0QCtZnPx0LFDcPMUX7Qg328Twbm3c/Jx1d0XT/x9jcg= +golang.org/x/tools v0.0.0-20200213050514-49b8ac185c84/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.4 h1:WiKh4+/eMB2HaY7QhCfW/R7MuRAoA8QMCSJA6jP5/fo= -google.golang.org/appengine v1.6.4/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190321212433-e79c0c59cdb5/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b h1:c8OBoXP3kTbDWWB/oVE3FkR851p4iZ3MPadz7zXEIPU= +google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.14.0 h1:ArxJuB1NWfPY6r9Gp9gqwplT0Ge7nqv9msgu03lHLmo= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= -gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= -gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/olivere/elastic.v5 v5.0.82/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0= +gopkg.in/olivere/elastic.v6 v6.2.27/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -540,13 +645,19 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= willnorris.com/go/gifresize v1.0.0/go.mod h1:eBM8gogBGCcaH603vxSpnfjwXIpq6nmnj/jauBDKtAk= willnorris.com/go/imageproxy v0.9.0/go.mod h1:SVC/wfHtCS4kjk3llMeuV4KlTN3a8XTgFWI8o7i3Avg= diff --git a/server/api.go b/server/api.go index 2138a2067..029a32f54 100644 --- a/server/api.go +++ b/server/api.go @@ -16,7 +16,7 @@ import ( "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/server/command.go b/server/command.go index 26d617a1a..de1ef0473 100644 --- a/server/command.go +++ b/server/command.go @@ -8,7 +8,7 @@ import ( "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/plugin" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" "github.com/mattermost/mattermost-server/v5/model" ) diff --git a/server/permalinks.go b/server/permalinks.go index 95594682c..98a502b41 100644 --- a/server/permalinks.go +++ b/server/permalinks.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" ) // maxPermalinkReplacements sets the maximum limit to the number of diff --git a/server/permalinks_test.go b/server/permalinks_test.go index 645df2a99..eda9e50d8 100644 --- a/server/permalinks_test.go +++ b/server/permalinks_test.go @@ -7,7 +7,7 @@ import ( "net/url" "testing" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/server/plugin.go b/server/plugin.go index 2691e7b47..ec286ca2a 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -20,7 +20,7 @@ import ( "github.com/mattermost/mattermost-server/v5/plugin" "github.com/pkg/errors" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/server/subscriptions.go b/server/subscriptions.go index 7674800e4..e3d5cb372 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -10,7 +10,7 @@ import ( "github.com/mattermost/mattermost-server/v5/mlog" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" ) const ( diff --git a/server/template_test.go b/server/template_test.go index 81264e99c..af2d93fdb 100644 --- a/server/template_test.go +++ b/server/template_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" "github.com/stretchr/testify/require" ) @@ -332,7 +332,7 @@ func TestPushedCommitsTemplate(t *testing.T) { Repo: &pushEventRepository, Sender: &user, Forced: bToP(false), - Commits: []github.PushEventCommit{ + Commits: []*github.HeadCommit{ { ID: sToP("a10867b14bb761a232cd80139fbd4c0d33264240"), URL: sToP("https://github.com/mattermost/mattermost-plugin-github/commit/a10867b14bb761a232cd80139fbd4c0d33264240"), @@ -359,7 +359,7 @@ func TestPushedCommitsTemplate(t *testing.T) { Repo: &pushEventRepository, Sender: &user, Forced: bToP(true), - Commits: []github.PushEventCommit{ + Commits: []*github.HeadCommit{ { ID: sToP("a10867b14bb761a232cd80139fbd4c0d33264240"), URL: sToP("https://github.com/mattermost/mattermost-plugin-github/commit/a10867b14bb761a232cd80139fbd4c0d33264240"), @@ -387,7 +387,7 @@ func TestPushedCommitsTemplate(t *testing.T) { Repo: &pushEventRepository, Sender: &user, Forced: bToP(false), - Commits: []github.PushEventCommit{ + Commits: []*github.HeadCommit{ { ID: sToP("a10867b14bb761a232cd80139fbd4c0d33264240"), URL: sToP("https://github.com/mattermost/mattermost-plugin-github/commit/a10867b14bb761a232cd80139fbd4c0d33264240"), @@ -424,7 +424,7 @@ func TestPushedCommitsTemplate(t *testing.T) { Repo: &pushEventRepository, Sender: &user, Forced: bToP(false), - Commits: []github.PushEventCommit{ + Commits: []*github.HeadCommit{ { ID: sToP("a10867b14bb761a232cd80139fbd4c0d33264240"), URL: sToP("https://github.com/mattermost/mattermost-plugin-github/commit/a10867b14bb761a232cd80139fbd4c0d33264240"), diff --git a/server/webhook.go b/server/webhook.go index 93de94c1d..f25920198 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -13,7 +13,7 @@ import ( "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" - "github.com/google/go-github/v25/github" + "github.com/google/go-github/v31/github" ) func verifyWebhookSignature(secret []byte, signature string, body []byte) (bool, error) { From 8be86b0727e8d20b08789117358e4402e8a20871 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 25 Apr 2020 20:11:02 +0200 Subject: [PATCH 07/16] Fix typo --- server/subscriptions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/subscriptions.go b/server/subscriptions.go index e3d5cb372..7e77c8a88 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -149,7 +149,7 @@ func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, use func (p *Plugin) SubscribeOrg(ctx context.Context, githubClient *github.Client, userID, org, channelID, features string, flags SubscriptionFlags) error { if org == "" { - return fmt.Errorf("envalid organization") + return fmt.Errorf("invalid organization") } return p.Subscribe(ctx, githubClient, userID, org, "", channelID, features, flags) From c24908b7ec32fa9b8644b0dd2dc27c6821d93244 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Mon, 27 Apr 2020 17:01:49 +0200 Subject: [PATCH 08/16] Consistent import odering --- server/api.go | 4 +--- server/command.go | 5 ++--- server/permalinks_test.go | 3 +-- server/plugin.go | 4 +--- server/subscriptions.go | 3 +-- server/webhook.go | 3 +-- 6 files changed, 7 insertions(+), 15 deletions(-) diff --git a/server/api.go b/server/api.go index 029a32f54..82669006e 100644 --- a/server/api.go +++ b/server/api.go @@ -10,13 +10,11 @@ import ( "sync" "time" + "github.com/google/go-github/v31/github" "github.com/gorilla/mux" - "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin" - - "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/server/command.go b/server/command.go index de1ef0473..e4c1d2ac7 100644 --- a/server/command.go +++ b/server/command.go @@ -5,11 +5,10 @@ import ( "fmt" "strings" - "github.com/mattermost/mattermost-server/v5/mlog" - "github.com/mattermost/mattermost-server/v5/plugin" - "github.com/google/go-github/v31/github" + "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/plugin" ) const commandHelp = `* |/github connect [private]| - Connect your Mattermost account to your GitHub account. diff --git a/server/permalinks_test.go b/server/permalinks_test.go index eda9e50d8..3d4f325fb 100644 --- a/server/permalinks_test.go +++ b/server/permalinks_test.go @@ -8,11 +8,10 @@ import ( "testing" "github.com/google/go-github/v31/github" + "github.com/mattermost/mattermost-server/v5/plugin/plugintest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - - "github.com/mattermost/mattermost-server/v5/plugin/plugintest" ) func TestGetReplacements(t *testing.T) { diff --git a/server/plugin.go b/server/plugin.go index ec286ca2a..6af3803ed 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -13,14 +13,12 @@ import ( "strings" "sync" + "github.com/google/go-github/v31/github" "github.com/gorilla/mux" - "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin" "github.com/pkg/errors" - - "github.com/google/go-github/v31/github" "golang.org/x/oauth2" ) diff --git a/server/subscriptions.go b/server/subscriptions.go index 7e77c8a88..3477f18b0 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -8,9 +8,8 @@ import ( "sort" "strings" - "github.com/mattermost/mattermost-server/v5/mlog" - "github.com/google/go-github/v31/github" + "github.com/mattermost/mattermost-server/v5/mlog" ) const ( diff --git a/server/webhook.go b/server/webhook.go index f25920198..32917e330 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -10,10 +10,9 @@ import ( "net/http" "strings" + "github.com/google/go-github/v31/github" "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" - - "github.com/google/go-github/v31/github" ) func verifyWebhookSignature(secret []byte, signature string, body []byte) (bool, error) { From 203413d6f95ae20e18c85809a112ce799df3667d Mon Sep 17 00:00:00 2001 From: Hanzei Date: Fri, 1 May 2020 07:46:55 +0200 Subject: [PATCH 09/16] Drop hasBeenNotified --- server/api.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/server/api.go b/server/api.go index 82669006e..072125d82 100644 --- a/server/api.go +++ b/server/api.go @@ -401,16 +401,18 @@ func (p *Plugin) getConnected(w http.ResponseWriter, r *http.Request, userID str privateRepoStoreKey := info.UserID + githubPrivateRepoKey if config.EnablePrivateRepo && !info.AllowedPrivateRepos { - hasBeenNotified := false val, err := p.API.KVGet(privateRepoStoreKey) if err != nil { mlog.Error("Unable to get private repo key value, err=" + err.Error()) + return } - hasBeenNotified = val != nil - if !hasBeenNotified { + // Inform the user once that private repositories enabled + if val == nil { p.CreateBotDMPost(info.UserID, "Private repositories have been enabled for this plugin. To be able to use them you must disconnect and reconnect your GitHub account. To reconnect your account, use the following slash commands: `/github disconnect` followed by `/github connect private`.", "") - if err := p.API.KVSet(privateRepoStoreKey, []byte("1")); err != nil { + + err := p.API.KVSet(privateRepoStoreKey, []byte("1")) + if err != nil { mlog.Error("Unable to set private repo key value, err=" + err.Error()) } } From 0953348ee0956cd2478bfdbc97220f14a6261bc3 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 2 May 2020 15:07:02 +0200 Subject: [PATCH 10/16] Add comment why crypto/sha1 is needed --- server/subscriptions.go | 2 +- server/webhook.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/subscriptions.go b/server/subscriptions.go index 3477f18b0..90e76cfbc 100644 --- a/server/subscriptions.go +++ b/server/subscriptions.go @@ -22,7 +22,7 @@ type SubscriptionFlags struct { } func (s *SubscriptionFlags) AddFlag(flag string) { - switch flag { // nolint:gocritic + switch flag { // nolint:gocritic // It's expected that more flags get added. case excludeOrgMemberFlag: s.ExcludeOrgMembers = true } diff --git a/server/webhook.go b/server/webhook.go index 32917e330..213443db3 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -3,7 +3,7 @@ package main import ( "context" "crypto/hmac" - "crypto/sha1" //nolint:gosec + "crypto/sha1" //nolint:gosec // GitHub webhooks are signed using sha1 https://developer.github.com/webhooks/. "encoding/hex" "fmt" "io/ioutil" From fb01beb6aff7239d86a6e267ba73e5d41012d5bc Mon Sep 17 00:00:00 2001 From: Hanzei Date: Wed, 6 May 2020 20:53:50 +0200 Subject: [PATCH 11/16] s/GET/http.MethodGet/g --- server/api.go | 34 +++++++++++++++++----------------- server/api_test.go | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/server/api.go b/server/api.go index 072125d82..4be80516b 100644 --- a/server/api.go +++ b/server/api.go @@ -85,23 +85,23 @@ func (p *Plugin) initializeAPI() { oauthRouter := p.router.PathPrefix("/oauth").Subrouter() apiRouter := p.router.PathPrefix("/api/v1").Subrouter() - p.router.HandleFunc("/webhook", p.handleWebhook).Methods("POST") - - oauthRouter.HandleFunc("/connect", p.extractUserMiddleWare(p.connectUserToGitHub, false)).Methods("GET") - oauthRouter.HandleFunc("/complete", p.extractUserMiddleWare(p.completeConnectUserToGitHub, false)).Methods("GET") - - apiRouter.HandleFunc("/connected", p.extractUserMiddleWare(p.getConnected, true)).Methods("GET") - apiRouter.HandleFunc("/todo", p.extractUserMiddleWare(p.postToDo, true)).Methods("POST") - apiRouter.HandleFunc("/reviews", p.extractUserMiddleWare(p.getReviews, false)).Methods("GET") - apiRouter.HandleFunc("/yourprs", p.extractUserMiddleWare(p.getYourPrs, false)).Methods("GET") - apiRouter.HandleFunc("/prsdetails", p.extractUserMiddleWare(p.getPrsDetails, false)).Methods("POST") - apiRouter.HandleFunc("/searchissues", p.extractUserMiddleWare(p.searchIssues, false)).Methods("GET") - apiRouter.HandleFunc("/yourassignments", p.extractUserMiddleWare(p.getYourAssignments, false)).Methods("GET") - apiRouter.HandleFunc("/createissuecomment", p.extractUserMiddleWare(p.createIssueComment, false)).Methods("POST") - apiRouter.HandleFunc("/mentions", p.extractUserMiddleWare(p.getMentions, false)).Methods("GET") - apiRouter.HandleFunc("/unreads", p.extractUserMiddleWare(p.getUnreads, false)).Methods("GET") - apiRouter.HandleFunc("/settings", p.extractUserMiddleWare(p.updateSettings, false)).Methods("POST") - apiRouter.HandleFunc("/user", p.extractUserMiddleWare(p.getGitHubUser, true)).Methods("POST") + p.router.HandleFunc("/webhook", p.handleWebhook).Methods(http.MethodPost) + + oauthRouter.HandleFunc("/connect", p.extractUserMiddleWare(p.connectUserToGitHub, false)).Methods(http.MethodGet) + oauthRouter.HandleFunc("/complete", p.extractUserMiddleWare(p.completeConnectUserToGitHub, false)).Methods(http.MethodGet) + + apiRouter.HandleFunc("/connected", p.extractUserMiddleWare(p.getConnected, true)).Methods(http.MethodGet) + apiRouter.HandleFunc("/todo", p.extractUserMiddleWare(p.postToDo, true)).Methods(http.MethodPost) + apiRouter.HandleFunc("/reviews", p.extractUserMiddleWare(p.getReviews, false)).Methods(http.MethodGet) + apiRouter.HandleFunc("/yourprs", p.extractUserMiddleWare(p.getYourPrs, false)).Methods(http.MethodGet) + apiRouter.HandleFunc("/prsdetails", p.extractUserMiddleWare(p.getPrsDetails, false)).Methods(http.MethodPost) + apiRouter.HandleFunc("/searchissues", p.extractUserMiddleWare(p.searchIssues, false)).Methods(http.MethodGet) + apiRouter.HandleFunc("/yourassignments", p.extractUserMiddleWare(p.getYourAssignments, false)).Methods(http.MethodGet) + apiRouter.HandleFunc("/createissuecomment", p.extractUserMiddleWare(p.createIssueComment, false)).Methods(http.MethodPost) + apiRouter.HandleFunc("/mentions", p.extractUserMiddleWare(p.getMentions, false)).Methods(http.MethodGet) + apiRouter.HandleFunc("/unreads", p.extractUserMiddleWare(p.getUnreads, false)).Methods(http.MethodGet) + apiRouter.HandleFunc("/settings", p.extractUserMiddleWare(p.updateSettings, false)).Methods(http.MethodPost) + apiRouter.HandleFunc("/user", p.extractUserMiddleWare(p.getGitHubUser, true)).Methods(http.MethodPost) } func (p *Plugin) extractUserMiddleWare(handler HTTPHandlerFuncWithUser, jsonResponse bool) http.HandlerFunc { diff --git a/server/api_test.go b/server/api_test.go index 92c13aea7..5588c8f9e 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -30,7 +30,7 @@ func TestPlugin_ServeHTTP(t *testing.T) { name: "unauthorized test json", httpTest: httpTestJSON, request: testutils.Request{ - Method: "GET", + Method: http.MethodGet, URL: "/api/v1/connected", Body: nil, }, @@ -45,7 +45,7 @@ func TestPlugin_ServeHTTP(t *testing.T) { name: "unauthorized test http", httpTest: httpTestString, request: testutils.Request{ - Method: "GET", + Method: http.MethodGet, URL: "/api/v1/reviews", Body: nil, }, From 27ac79a2b9c8222fb236d4aa809e891cd6feff57 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sat, 9 May 2020 00:57:02 +0200 Subject: [PATCH 12/16] Move all features to consts --- server/command.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/server/command.go b/server/command.go index e4c1d2ac7..9cfdec99b 100644 --- a/server/command.go +++ b/server/command.go @@ -37,18 +37,23 @@ const commandHelp = `* |/github connect [private]| - Connect your Mattermost acc * |value| can be "on" or "off"` const ( - featureIssues = "issues" - featurePulls = "pulls" + featureIssues = "issues" + featurePulls = "pulls" + featurePushes = "pushes" + featureCreates = "creates" + featureDeletes = "deletes" + featureIssueComments = "issue_comments" + featurePullReviews = "pull_reviews" ) var validFeatures = map[string]bool{ - featureIssues: true, - featurePulls: true, - "pushes": true, - "creates": true, - "deletes": true, - "issue_comments": true, - "pull_reviews": true, + featureIssues: true, + featurePulls: true, + featurePushes: true, + featureCreates: true, + featureDeletes: true, + featureIssueComments: true, + featurePullReviews: true, } // validateFeatures returns false when 1 or more given features From 2b100084f9d2352a41cf38ad95935db6a0003a33 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Sun, 17 May 2020 09:37:48 +0200 Subject: [PATCH 13/16] Fix eslint warnings --- .../sidebar_buttons/sidebar_buttons.jsx | 12 +++++------ .../components/sidebar_right/github_items.jsx | 21 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx b/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx index c4bbcb647..abe6db6d0 100644 --- a/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx +++ b/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx @@ -97,7 +97,7 @@ export default class SidebarButtons extends React.PureComponent { Connect to your GitHub} + overlay={{'Connect to your GitHub'}} > Your open pull requests} + overlay={{'Your open pull requests'}} > Pull requests needing review} + overlay={{'Pull requests needing review'}} > this.openRHS(RHSStates.REVIEWS)} @@ -163,7 +163,7 @@ export default class SidebarButtons extends React.PureComponent { Your assignments} + overlay={{'Your assignments'}} > this.openRHS(RHSStates.ASSIGNMENTS)} @@ -176,7 +176,7 @@ export default class SidebarButtons extends React.PureComponent { Unread messages} + overlay={{'Unread messages'}} > this.openRHS(RHSStates.UNREADS)} @@ -189,7 +189,7 @@ export default class SidebarButtons extends React.PureComponent { Refresh} + overlay={{'Refresh'}} > - #{item.number} + {' #' + item.number} ); } @@ -57,7 +57,7 @@ function GithubItems(props) { target='_blank' rel='noopener noreferrer' > - #{item.number} + {' #' + item.number} ); } @@ -109,11 +109,11 @@ function GithubItems(props) { >
- {title}{status} + {title + status}
- {number} ({repoName}) + {number} {'(' + repoName + ')'}
- {(item.created_at || userName || milestone) && (
)} - {notificationReasons[item.reason]} - ) : null } + {item.reason ? ( + {(item.created_at || userName || milestone) && (
)} + {notificationReasons[item.reason]} +
) : null }
{reviews} @@ -242,7 +241,7 @@ function getReviewText(item, style, secondLine) { } else { reviewName = 'reviews'; } - reviews = ({approved} out of {totalReviewers} {reviewName} complete.); + reviews = ({approved + ' out of ' + totalReviewers + ' ' + reviewName + ' complete.'}); } if (changesRequested > 0) { @@ -250,7 +249,7 @@ function getReviewText(item, style, secondLine) { Changes Requested} + overlay={{'Changes Requested'}} >
From 51d0b509668ed9e6ef51edac9c2db3ce6526e426 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Tue, 19 May 2020 20:40:24 +0200 Subject: [PATCH 14/16] Update dependencies --- go.mod | 4 ++-- go.sum | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index ba94e022d..91f1baaa3 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ require ( github.com/Masterminds/sprig/v3 v3.1.0 github.com/google/go-github/v31 v31.0.0 github.com/gorilla/mux v1.7.4 - github.com/mattermost/mattermost-server/v5 v5.22.0 + github.com/mattermost/mattermost-server/v5 v5.23.0 github.com/mholt/archiver/v3 v3.3.0 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.5.1 - golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d ) diff --git a/go.sum b/go.sum index 9ada7ffd8..d033dbcf5 100644 --- a/go.sum +++ b/go.sum @@ -260,6 +260,8 @@ github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d h1:2DV7VIlEv6J5R5o github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ= github.com/mattermost/mattermost-server/v5 v5.22.0 h1:LxRm0WUhN4nkRbwGK/TmCRW3SBDbxNPbyu/+aSswJxU= github.com/mattermost/mattermost-server/v5 v5.22.0/go.mod h1:ML8BRTnmU/pS6gqRVWJDjl7tk5puO+bt5z1MiPuFHIA= +github.com/mattermost/mattermost-server/v5 v5.23.0 h1:iXa6+ht9GcmMR1EwhJAb30sXOJN3pYg1DuqUsiv7JuI= +github.com/mattermost/mattermost-server/v5 v5.23.0/go.mod h1:nMrt08IvThjybZpXPe/nqe/oJuvJxhqKkGI+m7M0R00= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs= github.com/mattermost/viper v1.0.4/go.mod h1:uc5hKG9lv4/KRwPOt2c1omOyirS/UnuA2TytiZQSFHM= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -283,6 +285,7 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/minio/minio-go/v6 v6.0.45/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= +github.com/minio/minio-go/v6 v6.0.53/go.mod h1:DIvC/IApeHX8q1BAMVCXSXwpmrmM+I+iBvhvztQorfI= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= @@ -366,6 +369,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rudderlabs/analytics-go v3.1.0+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30= github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7/go.mod h1:Oz4y6ImuOQZxynhbSXk7btjEfNBtGlj2dcaOvXl2FSM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/rwcarlsen/goexif v0.0.0-20190318171057-76e3344f7516/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -400,6 +404,7 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -527,6 +532,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From 91ea349165eb3c9ac0fea3f8b239aac61afb1d59 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Wed, 20 May 2020 07:07:26 +0200 Subject: [PATCH 15/16] go mod tidy --- go.sum | 5 ----- 1 file changed, 5 deletions(-) diff --git a/go.sum b/go.sum index d033dbcf5..4c4de453f 100644 --- a/go.sum +++ b/go.sum @@ -258,8 +258,6 @@ github.com/mattermost/gorp v2.0.1-0.20190301154413-3b31e9a39d05+incompatible/go. github.com/mattermost/gosaml2 v0.3.2/go.mod h1:Z429EIOiEi9kbq6yHoApfzlcXpa6dzRDc6pO+Vy2Ksk= github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d h1:2DV7VIlEv6J5R5o6tUcb3ZMKJYeeZuWZL7Rv1m23TgQ= github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ= -github.com/mattermost/mattermost-server/v5 v5.22.0 h1:LxRm0WUhN4nkRbwGK/TmCRW3SBDbxNPbyu/+aSswJxU= -github.com/mattermost/mattermost-server/v5 v5.22.0/go.mod h1:ML8BRTnmU/pS6gqRVWJDjl7tk5puO+bt5z1MiPuFHIA= github.com/mattermost/mattermost-server/v5 v5.23.0 h1:iXa6+ht9GcmMR1EwhJAb30sXOJN3pYg1DuqUsiv7JuI= github.com/mattermost/mattermost-server/v5 v5.23.0/go.mod h1:nMrt08IvThjybZpXPe/nqe/oJuvJxhqKkGI+m7M0R00= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs= @@ -284,7 +282,6 @@ github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08 github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -github.com/minio/minio-go/v6 v6.0.45/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/minio-go/v6 v6.0.53/go.mod h1:DIvC/IApeHX8q1BAMVCXSXwpmrmM+I+iBvhvztQorfI= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -530,8 +527,6 @@ golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAG golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= From 592a5e6258fbd6476ee3e6a7f06f3b5d54dbfdd6 Mon Sep 17 00:00:00 2001 From: Hanzei Date: Wed, 20 May 2020 12:42:51 +0200 Subject: [PATCH 16/16] Fix RHS title --- webapp/src/components/sidebar_right/github_items.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/components/sidebar_right/github_items.jsx b/webapp/src/components/sidebar_right/github_items.jsx index a38247465..d21ebb218 100644 --- a/webapp/src/components/sidebar_right/github_items.jsx +++ b/webapp/src/components/sidebar_right/github_items.jsx @@ -110,7 +110,7 @@ function GithubItems(props) { >
- {title + status} + {title}{status}