Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/interceptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ To use a GitLab `Interceptor` as a GitLab webhook validator, do the following:
3. Create a Kubernetes secret containing your secret value.
4. Pass the Kubernetes secret as a reference to your GitLab `Interceptor`.

**Note:** if `secretRef` is omitted, the `Interceptor` does not verify the webhook
token and accepts every request, and it logs a warning for each request it processes.
Always set `secretRef` unless the `EventListener` is only reachable by trusted senders.

To use a GitLab `Interceptor` as a filter for event data, specify the event types
you want the `Interceptor` to accept in the `eventTypes` field. The `Interceptor`
accepts data event types listed in [Events](https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html).
Expand Down Expand Up @@ -400,6 +404,9 @@ To use a Bitbucket `Interceptor` as a Bitbucket server webhook validator, do the
3. Create a Kubernetes secret containing your secret value.
4. Pass the Kubernetes secret as a reference to your Bitbucket `Interceptor`.

**Note:** if `secretRef` is omitted, the `Interceptor` does not verify the webhook
signature and accepts every request.

To use a Bitbucket `Interceptor` as a filter for event data, specify the event types
you want the `Interceptor` to accept in the `eventTypes` field. The `Interceptor`
accepts data event types listed in [Event payload](https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html).
Expand Down
4 changes: 4 additions & 0 deletions pkg/interceptors/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1"
"github.com/tektoncd/triggers/pkg/interceptors"
"google.golang.org/grpc/codes"
"knative.dev/pkg/logging"
)

var _ triggersv1.InterceptorInterface = (*InterceptorImpl)(nil)
Expand Down Expand Up @@ -93,6 +94,9 @@ func (w *InterceptorImpl) Process(ctx context.Context, r *triggersv1.Interceptor
return interceptors.Fail(codes.InvalidArgument, "Invalid X-GitLab-Token")
}
}
if p.SecretRef == nil {
logging.FromContext(ctx).Warn("GitLab interceptor is running without signature verification. Set params.secretRef to enable webhook authentication.")
}
return &triggersv1.InterceptorResponse{
Continue: true,
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/interceptors/gitlab/gitlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ limitations under the License.
package gitlab

import (
"context"
"net/http"
"testing"

triggersv1 "github.com/tektoncd/triggers/pkg/apis/triggers/v1beta1"
"github.com/tektoncd/triggers/pkg/interceptors"
"github.com/tektoncd/triggers/test"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest/observer"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fakekubeclient "knative.dev/pkg/client/injection/kube/client/fake"
"knative.dev/pkg/logging"
)

func TestInterceptor_ExecuteTrigger_ShouldContinue(t *testing.T) {
Expand Down Expand Up @@ -307,3 +312,50 @@ func TestInterceptor_Process_InvalidParams(t *testing.T) {
t.Fatalf("Interceptor.Process() expected res.Continue to be false but got %t. \nStatus.Err(): %v", res.Continue, res.Status.Err())
}
}

func TestInterceptor_Process_WarnsWithoutSecretRef(t *testing.T) {
tests := []struct {
name string
params map[string]interface{}
wantWarn bool
}{{
name: "no secretRef",
params: map[string]interface{}{},
wantWarn: true,
}, {
name: "with secretRef",
params: map[string]interface{}{
"secretRef": &triggersv1.SecretRef{SecretName: "mysecret", SecretKey: "token"},
},
wantWarn: false,
}}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core, logs := observer.New(zapcore.WarnLevel)
ctx := logging.WithLogger(context.Background(), zap.New(core).Sugar())
ctx, clientset := fakekubeclient.With(ctx, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "mysecret", Namespace: metav1.NamespaceDefault},
Data: map[string][]byte{"token": []byte("secret")},
})
req := &triggersv1.InterceptorRequest{
Body: "somepayload",
Header: http.Header{"X-Gitlab-Token": []string{"secret"}},
InterceptorParams: tt.params,
Context: &triggersv1.TriggerContext{
EventURL: "https://testing.example.com",
EventID: "abcde",
TriggerID: "namespaces/default/triggers/example-trigger",
},
}
w := &InterceptorImpl{SecretGetter: interceptors.DefaultSecretGetter(clientset.CoreV1())}
res := w.Process(ctx, req)
if !res.Continue {
t.Fatalf("expected res.Continue to be true, got status %v", res.Status.Err())
}
if got := logs.Len() > 0; got != tt.wantWarn {
t.Errorf("warning logged = %t, want %t", got, tt.wantWarn)
}
})
}
}
Loading