diff --git a/.github/security.md b/.github/security.md index bb7915590..806927737 100644 --- a/.github/security.md +++ b/.github/security.md @@ -16,8 +16,8 @@ your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. -Report security bugs in third-party packages to the person or team maintaining -the module. +Report security bugs in third-party software to the person or team maintaining +that software. ## Disclosure Policy @@ -28,7 +28,7 @@ involving the following steps: * Confirm the problem and determine the affected versions. * Audit code to find any potential similar problems. * Prepare fixes for all releases still under maintenance. These fixes will be - released as fast as possible to npm. + released as fast as possible to DockerHub. ## Comments on this Policy diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc59edff..d7966c016 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +### Added + +- disable github status for cron jobs +- support for action in conditionals, by [@bradrydzewski](https://github.com/bradrydzewski). [#2685](https://github.com/drone/drone/issues/2685). + +### Fixed + +- improve error when kubernetes malforms the port configuration, by [@bradrydzewski](https://github.com/bradrydzewski). [#2742](https://github.com/drone/drone/issues/2742). +- copy parameters from parent build when promoting, by [@bradrydzewski](https://github.com/bradrydzewski). [#2748](https://github.com/drone/drone/issues/2748). + +## [1.2.2] - 2019-07-29 +### Added + +- support for legacy environment variables +- support for legacy workspace based on repository name +- support for github deployment hooks +- provide base sha for github pull requests +- option to filter webhooks by event and type +- upgrade drone-yaml to v1.2.2 +- upgrade drone-runtime to v1.0.7 + +### Fixed + +- error when manually creating an empty user, by [@bradrydzewski](https://github.com/bradrydzewski). [#2738](https://github.com/drone/drone/issues/2738). ## [1.2.1] - 2019-06-11 ### Added diff --git a/cmd/drone-server/config/config.go b/cmd/drone-server/config/config.go index 18a0ef629..9d4906998 100644 --- a/cmd/drone-server/config/config.go +++ b/cmd/drone-server/config/config.go @@ -15,6 +15,7 @@ package config import ( + "errors" "fmt" "os" "strings" @@ -280,6 +281,7 @@ type ( // Webhook provides the webhook configuration. Webhook struct { + Events []string `envconfig:"DRONE_WEBHOOK_EVENTS"` Endpoint []string `envconfig:"DRONE_WEBHOOK_ENDPOINT"` Secret string `envconfig:"DRONE_WEBHOOK_SECRET"` SkipVerify bool `envconfig:"DRONE_WEBHOOK_SKIP_VERIFY"` @@ -390,6 +392,9 @@ func Environ() (Config, error) { defaultSession(&cfg) defaultCallback(&cfg) configureGithub(&cfg) + if err := kubernetesServiceConflict(&cfg); err != nil { + return cfg, err + } return cfg, err } @@ -498,6 +503,13 @@ func configureGithub(c *Config) { } } +func kubernetesServiceConflict(c *Config) error { + if strings.HasPrefix(c.Server.Port, "tcp://") { + return errors.New("Invalid port configuration. See https://discourse.drone.io/t/drone-server-changing-ports-protocol/4144") + } + return nil +} + // Bytes stores number bytes (e.g. megabytes) type Bytes int64 diff --git a/cmd/drone-server/inject_plugin.go b/cmd/drone-server/inject_plugin.go index 7a7510e7d..7e3cd50e8 100644 --- a/cmd/drone-server/inject_plugin.go +++ b/cmd/drone-server/inject_plugin.go @@ -97,6 +97,7 @@ func provideSecretPlugin(config spec.Config) core.SecretService { // a webhook plugin based on the environment configuration. func provideWebhookPlugin(config spec.Config, system *core.System) core.WebhookSender { return webhook.New(webhook.Config{ + Events: config.Webhook.Events, Endpoint: config.Webhook.Endpoint, Secret: config.Webhook.Secret, System: system, diff --git a/core/webhook.go b/core/webhook.go index 1befa0c0d..d4a87b3fd 100644 --- a/core/webhook.go +++ b/core/webhook.go @@ -44,7 +44,7 @@ type ( // WebhookData provides the webhook data. WebhookData struct { - Event string `json:"-"` + Event string `json:"event"` Action string `json:"action"` User *User `json:"user,omitempty"` Repo *Repository `json:"repo,omitempty"` diff --git a/go.mod b/go.mod index 57bc17621..bd66f9b5d 100644 --- a/go.mod +++ b/go.mod @@ -16,14 +16,14 @@ require ( github.com/docker/distribution v2.7.1+incompatible github.com/docker/go-connections v0.3.0 github.com/docker/go-units v0.3.3 - github.com/drone/drone-go v1.0.5-0.20190427184118-618e4496482e - github.com/drone/drone-runtime v1.0.6 + github.com/drone/drone-go v1.0.5 + github.com/drone/drone-runtime v1.0.7 github.com/drone/drone-ui v0.0.0-20190530175131-92ba3df1e0a9 - github.com/drone/drone-yaml v1.1.4-0.20190614011118-4889634ea9ae + github.com/drone/drone-yaml v1.2.2 github.com/drone/envsubst v1.0.1 github.com/drone/go-license v1.0.2 github.com/drone/go-login v1.0.4-0.20190311170324-2a4df4f242a2 - github.com/drone/go-scm v1.5.0 + github.com/drone/go-scm v1.5.1-0.20190718235211-75d6480d5332 github.com/drone/signal v1.0.0 github.com/dustin/go-humanize v1.0.0 github.com/ghodss/yaml v1.0.0 @@ -35,7 +35,7 @@ require ( github.com/golang/mock v1.1.1 github.com/golang/protobuf v1.2.0 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c - github.com/google/go-cmp v0.2.0 + github.com/google/go-cmp v0.3.0 github.com/google/go-jsonnet v0.12.1 github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf github.com/google/wire v0.2.1 @@ -43,7 +43,7 @@ require ( github.com/gorhill/cronexpr v0.0.0-20140423231348-a557574d6c02 github.com/gosimple/slug v1.3.0 github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f - github.com/h2non/gock v1.0.10 + github.com/h2non/gock v1.0.15 github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/go-cleanhttp v0.5.0 github.com/hashicorp/go-multierror v1.0.0 @@ -97,3 +97,5 @@ require ( k8s.io/klog v0.1.0 sigs.k8s.io/yaml v1.1.0 ) + +replace github.com/h2non/gock => gopkg.in/h2non/gock.v1 v1.0.14 diff --git a/go.sum b/go.sum index 46481fa89..19b20dc61 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/drone/drone-go v0.0.0-20190217024616-3e8b71333e59/go.mod h1:qVb1k1w9X github.com/drone/drone-go v1.0.4 h1:Yom1lix1Lmk3KmKIsBSQJF1bw0YR2lDGaFQrXxqHMko= github.com/drone/drone-go v1.0.5-0.20190427184118-618e4496482e h1:Z9dJNcs1IpyS52xsf5vjXMq7vSuBt48Il2dJgOzyCFM= github.com/drone/drone-go v1.0.5-0.20190427184118-618e4496482e/go.mod h1:GxyeGClYohaKNYJv/ZpsmVHtMJ7WhoT+uDaJNcDIrk4= +github.com/drone/drone-go v1.0.5 h1:KCDzcPoz5yo5DC4sGcLl+6FsUYbCXjBj9d//b5WP5J0= +github.com/drone/drone-go v1.0.5/go.mod h1:GxyeGClYohaKNYJv/ZpsmVHtMJ7WhoT+uDaJNcDIrk4= github.com/drone/drone-runtime v0.0.0-20190210191445-ad403a0ca24e h1:Eq0QI9lKe6T5pziU/Kes1xX6QKAA6ZfnYvaZZeyY5TU= github.com/drone/drone-runtime v0.0.0-20190210191445-ad403a0ca24e/go.mod h1:I+wJO4yvngCUAro6wKjkMbuPPDI/jRynqU0LTW+8J44= github.com/drone/drone-runtime v1.0.3 h1:0p7ASt0WXbLZRzMOw20e1ahV3YkamRhtZFkm8UvM+JA= @@ -50,6 +52,9 @@ github.com/drone/drone-runtime v1.0.5 h1:fEdUvKd5+l8BQaPXntjUtSIVLvGWo3Blgb/zrXL github.com/drone/drone-runtime v1.0.5/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs= github.com/drone/drone-runtime v1.0.6 h1:7aPvPCZI2uqt3IEmx/BZg+ml10+I5lE74lZ17Y7xy40= github.com/drone/drone-runtime v1.0.6/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs= +github.com/drone/drone-runtime v1.0.7-0.20190729202838-87c84080f4a1/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs= +github.com/drone/drone-runtime v1.0.7 h1:qviHrNmEdT3aYfQW3NYOuClHw2IU6CECSOfrXe8QLvY= +github.com/drone/drone-runtime v1.0.7/go.mod h1:+osgwGADc/nyl40J0fdsf8Z09bgcBZXvXXnLOY48zYs= github.com/drone/drone-ui v0.0.0-20190318170755-1ca48466a158 h1:u80WYtaGkKWVmxj1BMX9SukAqTxILzGFIKvY5as9zAc= github.com/drone/drone-ui v0.0.0-20190318170755-1ca48466a158/go.mod h1:NBtVWW7NNJpD9+huMD/5TAE1db2nrEh0i35/9Rf1MPI= github.com/drone/drone-ui v0.0.0-20190318215801-d6c3d11a1c3f h1:yMdZ/2BZFKrfMbWlc0cNH2TCXdC8MsSR0pnu3Dq4UH4= @@ -85,6 +90,14 @@ github.com/drone/drone-yaml v1.1.4-0.20190610220437-a338c245d7d7 h1:xpnCbq/pHAYL github.com/drone/drone-yaml v1.1.4-0.20190610220437-a338c245d7d7/go.mod h1:l/ehbHx9TGs4jgzhRnP5d+M9tmRsAmWyBHWAFEOXrk4= github.com/drone/drone-yaml v1.1.4-0.20190614011118-4889634ea9ae h1:CzpY1F9Ju46gw4lbXwXrZCGyiAuP8QAlYtMcwYTVtW8= github.com/drone/drone-yaml v1.1.4-0.20190614011118-4889634ea9ae/go.mod h1:l/ehbHx9TGs4jgzhRnP5d+M9tmRsAmWyBHWAFEOXrk4= +github.com/drone/drone-yaml v1.2.1-0.20190717150947-d14ac477f983 h1:J59SqAC/DA1FuOXUvtGfYlhZSHegJL+AF9PnhXsxbKA= +github.com/drone/drone-yaml v1.2.1-0.20190717150947-d14ac477f983/go.mod h1:l/ehbHx9TGs4jgzhRnP5d+M9tmRsAmWyBHWAFEOXrk4= +github.com/drone/drone-yaml v1.2.2-0.20190719011530-e8b24d482cda h1:vPXJLgkyScZ0WnjzATIUcQbSRUjcP9BtnC+CMA1sSOk= +github.com/drone/drone-yaml v1.2.2-0.20190719011530-e8b24d482cda/go.mod h1:l/ehbHx9TGs4jgzhRnP5d+M9tmRsAmWyBHWAFEOXrk4= +github.com/drone/drone-yaml v1.2.2-0.20190719012529-c50000a465ee h1:/zyEkv56+T6JxLkYgYYwZAMLKBgEnHA3fwZXiVI9nuE= +github.com/drone/drone-yaml v1.2.2-0.20190719012529-c50000a465ee/go.mod h1:l/ehbHx9TGs4jgzhRnP5d+M9tmRsAmWyBHWAFEOXrk4= +github.com/drone/drone-yaml v1.2.2 h1:Srf8OlAHhR7SXX5Ax01dP5tpZENsrEKyg35E2nNkIew= +github.com/drone/drone-yaml v1.2.2/go.mod h1:QsqliFK8nG04AHFN9tTn9XJomRBQHD4wcejWW1uz/10= github.com/drone/envsubst v1.0.1 h1:NOOStingM2sbBwsIUeQkKUz8ShwCUzmqMxWrpXItfPE= github.com/drone/envsubst v1.0.1/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0= github.com/drone/go-license v1.0.2 h1:7OwndfYk+Lp/cGHkxe4HUn/Ysrrw3WYH2pnd99yrkok= @@ -105,6 +118,10 @@ github.com/drone/go-scm v1.4.1-0.20190418181654-1e77204716f6 h1:xQ0riJTnWFLZcpXr github.com/drone/go-scm v1.4.1-0.20190418181654-1e77204716f6/go.mod h1:YT4FxQ3U/ltdCrBJR9B0tRpJ1bYA/PM3NyaLE/rYIvw= github.com/drone/go-scm v1.5.0 h1:Hn3bFYsUgOEUCx2wt2II9CxkTfev2h+tPheuYHp7ehg= github.com/drone/go-scm v1.5.0/go.mod h1:YT4FxQ3U/ltdCrBJR9B0tRpJ1bYA/PM3NyaLE/rYIvw= +github.com/drone/go-scm v1.5.1-0.20190714160251-dee92a80f783 h1:dA3FngN241oZKI+PAjMdKX22nT8giYMlOY0JIt/qH/Y= +github.com/drone/go-scm v1.5.1-0.20190714160251-dee92a80f783/go.mod h1:YT4FxQ3U/ltdCrBJR9B0tRpJ1bYA/PM3NyaLE/rYIvw= +github.com/drone/go-scm v1.5.1-0.20190718235211-75d6480d5332 h1:QdYrRquj9e0sidvgjwYGdK4OB0WyQY6j5msjZ9sLUX8= +github.com/drone/go-scm v1.5.1-0.20190718235211-75d6480d5332/go.mod h1:YT4FxQ3U/ltdCrBJR9B0tRpJ1bYA/PM3NyaLE/rYIvw= github.com/drone/signal v1.0.0 h1:NrnM2M/4yAuU/tXs6RP1a1ZfxnaHwYkd0kJurA1p6uI= github.com/drone/signal v1.0.0/go.mod h1:S8t92eFT0g4WUgEc/LxG+LCuiskpMNsG0ajAMGnyZpc= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= @@ -131,6 +148,7 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCy github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-jsonnet v0.12.1 h1:v0iUm/b4SBz7lR/diMoz9tLAz8lqtnNRKIwMrmU2HEU= github.com/google/go-jsonnet v0.12.1/go.mod h1:gVu3UVSfOt5fRFq+dh9duBqXa5905QY8S1QvMNcEIVs= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= @@ -148,6 +166,8 @@ github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f/go.mod h1:Fecb github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= github.com/h2non/gock v1.0.10 h1:EzHYzKKSLN4xk0w193uAy3tp8I3+L1jmaI2Mjg4lCgU= github.com/h2non/gock v1.0.10/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= @@ -192,6 +212,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4 h1:dnMxwus89s86tI8rcGVp2HwZzlz7c5o92VOy7dSckBQ= github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4/go.mod h1:cojhOHk1gbMeklOyDP2oKKLftefXoJreOQGOrXk+Z38= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= @@ -260,6 +281,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/h2non/gock.v1 v1.0.14 h1:fTeu9fcUvSnLNacYvYI54h+1/XEteDyHvrVCZEEEYNM= +gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/handler/api/acl/acl_test.go b/handler/api/acl/acl_test.go index 3bb61115b..2b7eb04cd 100644 --- a/handler/api/acl/acl_test.go +++ b/handler/api/acl/acl_test.go @@ -10,8 +10,8 @@ import ( "net/http/httptest" "testing" - "github.com/drone/drone/handler/api/request" "github.com/drone/drone/core" + "github.com/drone/drone/handler/api/request" "github.com/sirupsen/logrus" ) @@ -22,9 +22,17 @@ func init() { var ( mockUser = &core.User{ - ID: 1, - Login: "octocat", - Admin: false, + ID: 1, + Login: "octocat", + Admin: false, + Active: true, + } + + mockUserInactive = &core.User{ + ID: 1, + Login: "octocat", + Admin: false, + Active: false, } mockRepo = &core.Repository{ diff --git a/handler/api/acl/check.go b/handler/api/acl/check.go index ecaad538b..2eaf6f7ed 100644 --- a/handler/api/acl/check.go +++ b/handler/api/acl/check.go @@ -123,6 +123,9 @@ func CheckAccess(read, write, admin bool) func(http.Handler) http.Handler { ) switch { + case user.Active == false: + render.Forbidden(w, errors.ErrForbidden) + log.Debugln("api: active account required") case read == true && perm.Read == false: render.NotFound(w, errors.ErrNotFound) log.Debugln("api: read access required") diff --git a/handler/api/acl/check_test.go b/handler/api/acl/check_test.go index 6adef6f6e..3221641ce 100644 --- a/handler/api/acl/check_test.go +++ b/handler/api/acl/check_test.go @@ -12,9 +12,9 @@ import ( "testing" "time" + "github.com/drone/drone/core" "github.com/drone/drone/handler/api/errors" "github.com/drone/drone/handler/api/request" - "github.com/drone/drone/core" "github.com/google/go-cmp/cmp" "github.com/go-chi/chi" @@ -380,6 +380,47 @@ func TestCheckWriteAccess(t *testing.T) { } } +// this test verifies the the next handler in the middleware +// chain is not processed if the user has write access BUT +// has been inactivated (e.g. blocked). +func TestCheckWriteAccess_InactiveUser(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + writeAccess := &core.Perm{ + Synced: time.Now().Unix(), + Read: true, + Write: true, + Admin: false, + } + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/api/repos/octocat/hello-world", nil) + r = r.WithContext( + request.WithPerm( + request.WithUser( + request.WithRepo(noContext, mockRepo), + mockUserInactive, + ), + writeAccess, + ), + ) + + router := chi.NewRouter() + router.Route("/api/repos/{owner}/{name}", func(router chi.Router) { + router.Use(CheckWriteAccess()) + router.Get("/", func(w http.ResponseWriter, r *http.Request) { + t.Error("should not invoke hanlder") + }) + }) + + router.ServeHTTP(w, r) + + if got, want := w.Code, http.StatusForbidden; got != want { + t.Errorf("Want status code %d, got %d", want, got) + } +} + // this test verifies that a 404 not found error is written to // the response if the user lacks write access to the repository. // @@ -526,7 +567,7 @@ func TestCheckAdminAccess_SystemAdmin(t *testing.T) { controller := gomock.NewController(t) defer controller.Finish() - user := &core.User{ID: 1, Admin: true} + user := &core.User{ID: 1, Admin: true, Active: true} w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/api/repos/octocat/hello-world", nil) diff --git a/handler/api/repos/builds/promote.go b/handler/api/repos/builds/promote.go index 9b36d5cb5..6b5a6362e 100644 --- a/handler/api/repos/builds/promote.go +++ b/handler/api/repos/builds/promote.go @@ -75,6 +75,10 @@ func HandlePromote( Params: map[string]string{}, } + for k, v := range prev.Params { + hook.Params[k] = v + } + for key, value := range r.URL.Query() { if key == "access_token" { continue diff --git a/handler/api/users/create.go b/handler/api/users/create.go index b10f4291b..c48bc7240 100644 --- a/handler/api/users/create.go +++ b/handler/api/users/create.go @@ -55,9 +55,15 @@ func HandleCreate(users core.UserStore, sender core.WebhookSender) http.HandlerF if user.Hash == "" { user.Hash = uniuri.NewLen(32) } - // - // TODO(bradrydzewski) validate the user.Login with a user.Validate() function - // + + err = user.Validate() + if err != nil { + render.ErrorCode(w, err, 400) + logger.FromRequest(r).WithError(err). + Errorln("api: invlid username") + return + } + err = users.Create(r.Context(), user) if err == core.ErrUserLimit { render.ErrorCode(w, err, 402) diff --git a/operator/runner/env.go b/operator/runner/env.go index 02d54bea1..03c05b226 100644 --- a/operator/runner/env.go +++ b/operator/runner/env.go @@ -56,6 +56,17 @@ func repoEnviron(repo *core.Repository) map[string]string { "DRONE_GIT_SSH_URL": repo.SSHURL, "DRONE_REPO_VISIBILITY": repo.Visibility, "DRONE_REPO_PRIVATE": fmt.Sprint(repo.Private), + + // + // these are legacy configuration parameters for backward + // compatibilty with drone 0.8. + // + "CI_REPO": repo.Slug, + "CI_REPO_NAME": repo.Slug, + "CI_REPO_LINK": repo.Link, + "CI_REPO_REMOTE": repo.HTTPURL, + "CI_REMOTE_URL": repo.HTTPURL, + "CI_REPO_PRIVATE": fmt.Sprint(repo.Private), } } @@ -96,6 +107,28 @@ func buildEnviron(build *core.Build) map[string]string { "DRONE_BUILD_STARTED": fmt.Sprint(build.Started), "DRONE_BUILD_FINISHED": fmt.Sprint(build.Finished), "DRONE_DEPLOY_TO": build.Deploy, + + // + // these are legacy configuration parameters for backward + // compatibilty with drone 0.8. + // + "CI_BUILD_NUMBER": fmt.Sprint(build.Number), + "CI_PARENT_BUILD_NUMBER": fmt.Sprint(build.Parent), + "CI_BUILD_CREATED": fmt.Sprint(build.Created), + "CI_BUILD_STARTED": fmt.Sprint(build.Started), + "CI_BUILD_FINISHED": fmt.Sprint(build.Finished), + "CI_BUILD_STATUS": build.Status, + "CI_BUILD_EVENT": build.Event, + "CI_BUILD_LINK": build.Link, + "CI_BUILD_TARGET": build.Deploy, + "CI_COMMIT_SHA": build.After, + "CI_COMMIT_REF": build.Ref, + "CI_COMMIT_BRANCH": build.Target, + "CI_COMMIT_MESSAGE": build.Message, + "CI_COMMIT_AUTHOR": build.Author, + "CI_COMMIT_AUTHOR_NAME": build.AuthorName, + "CI_COMMIT_AUTHOR_EMAIL": build.AuthorEmail, + "CI_COMMIT_AUTHOR_AVATAR": build.AuthorAvatar, } if strings.HasPrefix(build.Ref, "refs/tags/") { env["DRONE_TAG"] = strings.TrimPrefix(build.Ref, "refs/tags/") diff --git a/operator/runner/runner.go b/operator/runner/runner.go index 2f27c80b2..907ceffdf 100644 --- a/operator/runner/runner.go +++ b/operator/runner/runner.go @@ -188,6 +188,7 @@ func (r *Runner) Run(ctx context.Context, id int64) error { // the legacy yaml configuration file to the new format. y, err := converter.ConvertString(string(m.Config.Data), converter.Metadata{ Filename: m.Repo.Config, + URL: m.Repo.Link, Ref: m.Build.Ref, }) @@ -259,6 +260,7 @@ func (r *Runner) Run(ctx context.Context, id int64) error { ) comp.SkipFunc = compiler.SkipFunc( compiler.SkipData{ + Action: m.Build.Action, Branch: m.Build.Target, Cron: m.Build.Cron, Event: m.Build.Event, diff --git a/plugin/webhook/config.go b/plugin/webhook/config.go index d50315a6d..b712a041d 100644 --- a/plugin/webhook/config.go +++ b/plugin/webhook/config.go @@ -18,6 +18,7 @@ import "github.com/drone/drone/core" // Config provides the webhook configuration. type Config struct { + Events []string Endpoint []string Secret string System *core.System diff --git a/plugin/webhook/webhook.go b/plugin/webhook/webhook.go index d2e7dba64..b5f2fc512 100644 --- a/plugin/webhook/webhook.go +++ b/plugin/webhook/webhook.go @@ -13,6 +13,7 @@ import ( "encoding/base64" "encoding/json" "net/http" + "path/filepath" "time" "github.com/drone/drone/core" @@ -34,6 +35,7 @@ var signer = httpsignatures.NewSigner( // New returns a new Webhook sender. func New(config Config) core.WebhookSender { return &sender{ + Events: config.Events, Endpoints: config.Endpoint, Secret: config.Secret, System: config.System, @@ -47,6 +49,7 @@ type payload struct { type sender struct { Client *http.Client + Events []string Endpoints []string Secret string System *core.System @@ -58,6 +61,9 @@ func (s *sender) Send(ctx context.Context, in *core.WebhookData) error { if len(s.Endpoints) == 0 { return nil } + if s.match(in.Event, in.Action) == false { + return nil + } wrapper := payload{ WebhookData: in, System: s.System, @@ -96,6 +102,25 @@ func (s *sender) send(endpoint, secret, event string, data []byte) error { return err } +func (s *sender) match(event, action string) bool { + if len(s.Events) == 0 { + return true + } + var name string + switch { + case action == "": + name = event + case action != "": + name = event + ":" + action + } + for _, pattern := range s.Events { + if ok, _ := filepath.Match(pattern, name); ok { + return true + } + } + return false +} + func (s *sender) client() *http.Client { if s.Client == nil { return http.DefaultClient diff --git a/plugin/webhook/webhook_test.go b/plugin/webhook/webhook_test.go index f08219aad..4e4b7d7fc 100644 --- a/plugin/webhook/webhook_test.go +++ b/plugin/webhook/webhook_test.go @@ -41,7 +41,7 @@ func TestWebhook(t *testing.T) { AddMatcher(matchSignature). MatchHeader("X-Drone-Event", "user"). MatchHeader("Content-Type", "application/json"). - MatchHeader("Digest", "SHA-256=Rro8edtwJUjLl6e\\/xB9m1ykaymiaC9YxFGb\\/XNuXzO4="). + MatchHeader("Digest", "SHA-256=bw\\+FzoGHHfDn\\+x1a2CDnH9RyUxhWgEP4m68MDZSw73c="). JSON(webhook). Reply(200). Type("application/json") @@ -91,3 +91,73 @@ func TestWebhook_NoEndpoints(t *testing.T) { t.Error(err) } } + +func TestWebhook_NoMatch(t *testing.T) { + webhook := &core.WebhookData{ + Event: core.WebhookEventUser, + Action: core.WebhookActionCreated, + User: &core.User{Login: "octocat"}, + } + + config := Config{ + Events: []string{"repo:disabled"}, + Endpoint: []string{"https://localhost:1234"}, + Secret: "correct-horse-battery-staple", + } + sender := New(config) + err := sender.Send(noContext, webhook) + if err != nil { + t.Error(err) + } +} + +func TestWebhook_Match(t *testing.T) { + tests := []struct { + events []string + event string + action string + matched bool + }{ + { + event: "repo", + action: "enabled", + matched: true, + }, + { + events: []string{"user", "repo"}, + event: "repo", + matched: true, + }, + { + events: []string{"repo:disabled", "repo:enabled"}, + event: "repo", + action: "enabled", + matched: true, + }, + { + events: []string{"repo:disabled", "repo:*"}, + event: "repo", + action: "enabled", + matched: true, + }, + { + events: []string{"repo:disabled", "user:created"}, + event: "repo", + action: "enabled", + matched: false, + }, + { + events: []string{"repo", "user"}, + event: "repo", + action: "enabled", + matched: false, + }, + } + for i, test := range tests { + s := new(sender) + s.Events = test.events + if s.match(test.event, test.action) != test.matched { + t.Errorf("Expect matched %v at index %d", test.matched, i) + } + } +} diff --git a/scheduler/queue/queue.go b/scheduler/queue/queue.go index bce12f0e9..a849b4c86 100644 --- a/scheduler/queue/queue.go +++ b/scheduler/queue/queue.go @@ -151,24 +151,27 @@ func (q *queue) signal(ctx context.Context) error { continue } - // the worker is platform-specific. check to ensure - // the queue item matches the worker platform. - if w.os != item.OS { - continue - } - if w.arch != item.Arch { - continue - } - // if the pipeline defines a variant it must match - // the worker variant (e.g. arm6, arm7, etc). - if item.Variant != "" && item.Variant != w.variant { - continue - } - // if the pipeline defines a kernel version it must match - // the worker kernel version (e.g. 1709, 1803). - if item.Kernel != "" && item.Kernel != w.kernel { - continue + if w.os != "" || w.arch != "" || w.variant != "" || w.kernel != "" { + // the worker is platform-specific. check to ensure + // the queue item matches the worker platform. + if w.os != item.OS { + continue + } + if w.arch != item.Arch { + continue + } + // if the pipeline defines a variant it must match + // the worker variant (e.g. arm6, arm7, etc). + if item.Variant != "" && item.Variant != w.variant { + continue + } + // if the pipeline defines a kernel version it must match + // the worker kernel version (e.g. 1709, 1803). + if item.Kernel != "" && item.Kernel != w.kernel { + continue + } } + if len(item.Labels) > 0 || len(w.labels) > 0 { if !checkLabels(item.Labels, w.labels) { continue diff --git a/service/hook/hook.go b/service/hook/hook.go index 176aaa013..eb4641916 100644 --- a/service/hook/hook.go +++ b/service/hook/hook.go @@ -49,6 +49,7 @@ func (s *service) Create(ctx context.Context, user *core.User, repo *core.Reposi Secret: repo.Signer, Events: scm.HookEvents{ Branch: true, + Deployment: true, PullRequest: true, Push: true, Tag: true, diff --git a/service/hook/hook_test.go b/service/hook/hook_test.go index f92fb4038..10bf069be 100644 --- a/service/hook/hook_test.go +++ b/service/hook/hook_test.go @@ -8,9 +8,9 @@ import ( "context" "testing" + "github.com/drone/drone/core" "github.com/drone/drone/mock" "github.com/drone/drone/mock/mockscm" - "github.com/drone/drone/core" "github.com/drone/go-scm/scm" "github.com/golang/mock/gomock" @@ -37,6 +37,7 @@ func TestCreate(t *testing.T) { Secret: "abc123", Events: scm.HookEvents{ Branch: true, + Deployment: true, PullRequest: true, Push: true, Tag: true, diff --git a/service/hook/parser/parse.go b/service/hook/parser/parse.go index 8a193e4c6..34fa933c0 100644 --- a/service/hook/parser/parse.go +++ b/service/hook/parser/parse.go @@ -251,6 +251,7 @@ func (p *parser) Parse(req *http.Request, secretFunc func(string) string) (*core Timestamp: v.PullRequest.Created.Unix(), Title: v.PullRequest.Title, Message: v.PullRequest.Body, + Before: v.PullRequest.Base.Sha, After: v.PullRequest.Sha, Ref: v.PullRequest.Ref, Fork: v.PullRequest.Fork, diff --git a/service/status/status.go b/service/status/status.go index 215fcb49f..64c15a335 100644 --- a/service/status/status.go +++ b/service/status/status.go @@ -49,7 +49,7 @@ type service struct { } func (s *service) Send(ctx context.Context, user *core.User, req *core.StatusInput) error { - if s.disabled { + if s.disabled || req.Build.Trigger == core.TriggerCron { return nil } diff --git a/service/status/status_test.go b/service/status/status_test.go index e57a0c1c8..89d68551e 100644 --- a/service/status/status_test.go +++ b/service/status/status_test.go @@ -102,7 +102,7 @@ func TestStatus_RenewalError(t *testing.T) { mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(scm.ErrNotAuthorized) service := New(nil, mockRenewer, Config{Base: "https://drone.company.com"}) - err := service.Send(noContext, mockUser, nil) + err := service.Send(noContext, mockUser, &core.StatusInput{Build: &core.Build{}}) if err == nil { t.Errorf("Expect error refreshing token") } diff --git a/trigger/trigger.go b/trigger/trigger.go index fd5f0e743..a2940966b 100644 --- a/trigger/trigger.go +++ b/trigger/trigger.go @@ -198,6 +198,7 @@ func (t *triggerer) Trigger(ctx context.Context, repo *core.Repository, base *co // the legacy yaml configuration file to the new format. raw.Data, err = converter.ConvertString(raw.Data, converter.Metadata{ Filename: repo.Config, + URL: repo.Link, Ref: base.Ref, }) if err != nil { diff --git a/version/version.go b/version/version.go index 24ac097d7..e92c6a1c4 100644 --- a/version/version.go +++ b/version/version.go @@ -27,7 +27,7 @@ var ( // VersionMinor is for functionality in a backwards-compatible manner. VersionMinor int64 = 2 // VersionPatch is for backwards-compatible bug fixes. - VersionPatch int64 = 1 + VersionPatch int64 = 2 // VersionPre indicates prerelease. VersionPre = "" // VersionDev indicates development branch. Releases will be empty string. diff --git a/version/version_test.go b/version/version_test.go index 34c130a6a..d7e2ea7a5 100644 --- a/version/version_test.go +++ b/version/version_test.go @@ -9,7 +9,7 @@ package version import "testing" func TestVersion(t *testing.T) { - if got, want := Version.String(), "1.2.1"; got != want { + if got, want := Version.String(), "1.2.2"; got != want { t.Errorf("Want version %s, got %s", want, got) } }