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