@@ -874,7 +874,7 @@ func TestErrorReadingRequest(t *testing.T) {
874874 client : mockClient ,
875875 namespace : "default" ,
876876 }
877- testRequest := httptest .NewRequest ( http .MethodPost , "/something" , errReader (0 ))
877+ testRequest := httptest .NewRequestWithContext ( context . Background (), http .MethodPost , "/something" , errReader (0 ))
878878 rr := httptest .NewRecorder ()
879879 w .ServeHTTP (rr , testRequest )
880880
@@ -883,3 +883,83 @@ func TestErrorReadingRequest(t *testing.T) {
883883 t .Errorf ("handler returned wrong status code: got %v want %v" , status , http .StatusInternalServerError )
884884 }
885885}
886+
887+ // TestGitHubWildcardURLDoesNotMatchUnintendedRepo verifies that regex metacharacters
888+ // in a webhook payload's repo URL (e.g. a hostname or path of ".*") are treated as
889+ // literals and do not accidentally match GitRepos whose URLs are unrelated to the
890+ // webhook source.
891+ func TestGitHubWildcardURLDoesNotMatchUnintendedRepo (t * testing.T ) {
892+ tests := []struct {
893+ name string
894+ gitRepoURL string // the GitRepo's configured repo
895+ webhookRepoURL string // the repo URL embedded in the webhook payload
896+ }{
897+ {
898+ name : "wildcard hostname does not match unrelated gitrepo" ,
899+ gitRepoURL : "https://github.com/example/repo" ,
900+ webhookRepoURL : "https://.*/example/repo" ,
901+ },
902+ {
903+ name : "wildcard path does not match unrelated gitrepo" ,
904+ gitRepoURL : "https://github.com/example/repo" ,
905+ webhookRepoURL : "https://github.com/.*/.*" ,
906+ },
907+ {
908+ name : "wildcard hostname and path do not match unrelated gitrepo" ,
909+ gitRepoURL : "https://github.com/example/repo" ,
910+ webhookRepoURL : "https://.*/.*" ,
911+ },
912+ }
913+
914+ for _ , tt := range tests {
915+ t .Run (tt .name , func (t * testing.T ) {
916+ sch := runtime .NewScheme ()
917+ if err := v1alpha1 .AddToScheme (sch ); err != nil {
918+ t .Fatalf ("unable to add to scheme: %v" , err )
919+ }
920+ utilruntime .Must (corev1 .AddToScheme (sch ))
921+
922+ gitRepo := & v1alpha1.GitRepo {
923+ ObjectMeta : metav1.ObjectMeta {
924+ Name : "test" ,
925+ Namespace : "default" ,
926+ },
927+ Spec : v1alpha1.GitRepoSpec {
928+ Repo : tt .gitRepoURL ,
929+ Branch : "main" ,
930+ },
931+ }
932+ fakeClient := cfake .NewClientBuilder ().
933+ WithScheme (sch ).
934+ WithRuntimeObjects (gitRepo ).
935+ WithStatusSubresource (gitRepo ).
936+ Build ()
937+
938+ w := & Webhook {client : fakeClient , namespace : "default" }
939+
940+ commit := "af69d162de5a276abc86e0686b2b44033cd3f442"
941+ jsonBody := fmt .Appendf (nil , `{
942+ "ref": "refs/heads/main",
943+ "after": "%s",
944+ "repository": {"html_url": "%s"}
945+ }` , commit , tt .webhookRepoURL )
946+
947+ req , err := http .NewRequestWithContext (context .Background (), http .MethodPost , "/" , bytes .NewReader (jsonBody ))
948+ if err != nil {
949+ t .Fatalf ("failed to create request: %v" , err )
950+ }
951+ req .Header .Set ("X-GitHub-Event" , "push" )
952+
953+ rr := httptest .NewRecorder ()
954+ w .ServeHTTP (rr , req )
955+
956+ updated := & v1alpha1.GitRepo {}
957+ if err := fakeClient .Get (context .TODO (), types.NamespacedName {Name : gitRepo .Name , Namespace : gitRepo .Namespace }, updated ); err != nil {
958+ t .Fatalf ("failed to get gitrepo: %v" , err )
959+ }
960+ if updated .Status .WebhookCommit != "" {
961+ t .Errorf ("expected WebhookCommit to remain empty (no match), but got %q" , updated .Status .WebhookCommit )
962+ }
963+ })
964+ }
965+ }
0 commit comments