option to return ErrSkip and ErrBlock from validator

pull/53/head
Brad Rydzewski 4 years ago
parent 195394da10
commit f02fb45ced

@ -1,5 +1,7 @@
module github.com/drone/drone-go
go 1.14
require (
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e
github.com/google/go-cmp v0.2.0

@ -0,0 +1,4 @@
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e h1:rl2Aq4ZODqTDkeSqQBy+fzpZPamacO1Srp8zq7jf2Sc=
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=

@ -17,6 +17,7 @@ package validator
import (
"context"
"github.com/drone/drone-go/drone"
"github.com/drone/drone-go/plugin/internal/client"
)
@ -34,5 +35,14 @@ type pluginClient struct {
}
func (c *pluginClient) Validate(ctx context.Context, in *Request) error {
return c.client.Do(in, nil)
err := c.client.Do(in, nil)
if xerr, ok := err.(*drone.Error); ok {
if xerr.Code == 498 {
return ErrSkip
}
if xerr.Code == 499 {
return ErrBlock
}
}
return err
}

@ -0,0 +1,51 @@
// Copyright 2018 Drone.IO Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validator
// import (
// "bytes"
// "context"
// "io/ioutil"
// "net/http"
// "testing"
// )
// var noContext = context.Background()
// func TestErrSkip(t *testing.T) {
// client := http.Client{}
// client.Transport = roundTripFunc(func(r *http.Request) (*http.Response, error) {
// buf := bytes.NewBuffer(nil)
// buf.WriteString("skip")
// return &http.Response{
// Body: ioutil.NopCloser(buf),
// StatusCode: 498,
// }, nil
// })
// plugin := Client("http://localhost", "top-secret", false)
// plugin.(*pluginClient).client.Client = &client
// err := plugin.Validate(noContext, &Request{})
// if err != ErrSkip {
// t.Errorf("Expect skip error, got %v", err)
// }
// }
// type roundTripFunc func(r *http.Request) (*http.Response, error)
// func (s roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) {
// return s(r)
// }

@ -90,6 +90,16 @@ func (p *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
if err == ErrSkip {
w.WriteHeader(498)
return
}
if err == ErrBlock {
w.WriteHeader(499)
return
}
// The error should be converted to a drone.Error so that
// it can be marshaled to JSON.
if _, ok := err.(*drone.Error); !ok {

@ -98,6 +98,68 @@ func TestHandler_Error(t *testing.T) {
}
}
func TestHandler_ErrorSkip(t *testing.T) {
key := "xVKAGlWQiY3sOp8JVc0nbuNId3PNCgWh"
buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(&Request{
Config: drone.Config{
Data: "{kind: pipeline, type: docker}",
},
})
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/", buf)
req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat))
err := httpsignatures.DefaultSha256Signer.AuthRequest("hmac-key", key, req)
if err != nil {
t.Error(err)
return
}
err = ErrSkip
plugin := &mockPlugin{err: err}
handler := Handler(key, plugin, nil)
handler.ServeHTTP(res, req)
if got, want := res.Code, 498; got != want {
t.Errorf("Want status code %d, got %d", want, got)
}
}
func TestHandler_ErrorBlock(t *testing.T) {
key := "xVKAGlWQiY3sOp8JVc0nbuNId3PNCgWh"
buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(&Request{
Config: drone.Config{
Data: "{kind: pipeline, type: docker}",
},
})
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/", buf)
req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat))
err := httpsignatures.DefaultSha256Signer.AuthRequest("hmac-key", key, req)
if err != nil {
t.Error(err)
return
}
err = ErrBlock
plugin := &mockPlugin{err: err}
handler := Handler(key, plugin, nil)
handler.ServeHTTP(res, req)
if got, want := res.Code, 499; got != want {
t.Errorf("Want status code %d, got %d", want, got)
}
}
func TestHandler_MissingSignature(t *testing.T) {
res := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/", nil)

@ -16,6 +16,7 @@ package validator
import (
"context"
"errors"
"github.com/drone/drone-go/drone"
)
@ -23,6 +24,14 @@ import (
// V1 is version 1 of the validator API
const V1 = "application/vnd.drone.validate.v1+json"
// ErrSkip is returned when the build should be skipped
// instead of throwing an error.
var ErrSkip = errors.New("skip")
// ErrBlock is returned when the build should be blocked
// instead of throwing an error.
var ErrBlock = errors.New("block")
type (
// Request defines a validator request.
Request struct {

Loading…
Cancel
Save