github.com/argoproj/argo-cd/v2@v2.10.9/server/server_norace_test.go (about) 1 //go:build !race 2 // +build !race 3 4 package server 5 6 import ( 7 "context" 8 "fmt" 9 "net/http" 10 "os" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/stretchr/testify/assert" 16 17 "github.com/argoproj/argo-cd/v2/common" 18 "github.com/argoproj/argo-cd/v2/pkg/apiclient" 19 applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" 20 "github.com/argoproj/argo-cd/v2/test" 21 ) 22 23 func TestUserAgent(t *testing.T) { 24 25 // !race: 26 // A data race in go-client's `shared_informer.go`, between `sharedProcessor.run(...)` and itself. Based on 27 // the data race, it APPEARS to be intentional, but in any case it's nothing we are doing in Argo CD 28 // that is causing this issue. 29 30 s, closer := fakeServer(t) 31 defer closer() 32 lns, err := s.Listen() 33 assert.NoError(t, err) 34 35 cancelInformer := test.StartInformer(s.projInformer) 36 defer cancelInformer() 37 ctx, cancel := context.WithCancel(context.Background()) 38 defer cancel() 39 s.Init(ctx) 40 go s.Run(ctx, lns) 41 defer func() { time.Sleep(3 * time.Second) }() 42 43 type testData struct { 44 userAgent string 45 errorMsg string 46 } 47 currentVersionBytes, err := os.ReadFile("../VERSION") 48 assert.NoError(t, err) 49 currentVersion := strings.TrimSpace(string(currentVersionBytes)) 50 var tests = []testData{ 51 { 52 // Reject out-of-date user-agent 53 userAgent: fmt.Sprintf("%s/0.10.0", common.ArgoCDUserAgentName), 54 errorMsg: "unsatisfied client version constraint", 55 }, 56 { 57 // Accept up-to-date user-agent 58 userAgent: fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, currentVersion), 59 }, 60 { 61 // Accept up-to-date pre-release user-agent 62 userAgent: fmt.Sprintf("%s/%s-rc1", common.ArgoCDUserAgentName, currentVersion), 63 }, 64 { 65 // Permit custom clients 66 userAgent: "foo/1.2.3", 67 }, 68 } 69 70 for _, test := range tests { 71 opts := apiclient.ClientOptions{ 72 ServerAddr: fmt.Sprintf("localhost:%d", s.ListenPort), 73 PlainText: true, 74 UserAgent: test.userAgent, 75 } 76 clnt, err := apiclient.NewClient(&opts) 77 assert.NoError(t, err) 78 conn, appClnt := clnt.NewApplicationClientOrDie() 79 _, err = appClnt.List(ctx, &applicationpkg.ApplicationQuery{}) 80 if test.errorMsg != "" { 81 assert.Error(t, err) 82 assert.Regexp(t, test.errorMsg, err.Error()) 83 } else { 84 assert.NoError(t, err) 85 } 86 _ = conn.Close() 87 } 88 } 89 90 func Test_StaticHeaders(t *testing.T) { 91 92 // !race: 93 // Same as TestUserAgent 94 95 // Test default policy "sameorigin" and "frame-ancestors 'self';" 96 { 97 s, closer := fakeServer(t) 98 defer closer() 99 lns, err := s.Listen() 100 assert.NoError(t, err) 101 cancelInformer := test.StartInformer(s.projInformer) 102 defer cancelInformer() 103 ctx, cancel := context.WithCancel(context.Background()) 104 defer cancel() 105 s.Init(ctx) 106 go s.Run(ctx, lns) 107 defer func() { time.Sleep(3 * time.Second) }() 108 109 // Allow server startup 110 time.Sleep(1 * time.Second) 111 112 client := http.Client{} 113 url := fmt.Sprintf("http://127.0.0.1:%d/test.html", s.ListenPort) 114 req, err := http.NewRequest(http.MethodGet, url, nil) 115 assert.NoError(t, err) 116 resp, err := client.Do(req) 117 assert.NoError(t, err) 118 assert.Equal(t, "sameorigin", resp.Header.Get("X-Frame-Options")) 119 assert.Equal(t, "frame-ancestors 'self';", resp.Header.Get("Content-Security-Policy")) 120 } 121 122 // Test custom policy for X-Frame-Options and Content-Security-Policy 123 { 124 s, closer := fakeServer(t) 125 defer closer() 126 s.XFrameOptions = "deny" 127 s.ContentSecurityPolicy = "frame-ancestors 'none';" 128 cancelInformer := test.StartInformer(s.projInformer) 129 defer cancelInformer() 130 lns, err := s.Listen() 131 assert.NoError(t, err) 132 ctx, cancel := context.WithCancel(context.Background()) 133 defer cancel() 134 s.Init(ctx) 135 go s.Run(ctx, lns) 136 defer func() { time.Sleep(3 * time.Second) }() 137 138 // Allow server startup 139 time.Sleep(1 * time.Second) 140 141 client := http.Client{} 142 url := fmt.Sprintf("http://127.0.0.1:%d/test.html", s.ListenPort) 143 req, err := http.NewRequest(http.MethodGet, url, nil) 144 assert.NoError(t, err) 145 resp, err := client.Do(req) 146 assert.NoError(t, err) 147 assert.Equal(t, "deny", resp.Header.Get("X-Frame-Options")) 148 assert.Equal(t, "frame-ancestors 'none';", resp.Header.Get("Content-Security-Policy")) 149 } 150 151 // Test disabled X-Frame-Options and Content-Security-Policy 152 { 153 s, closer := fakeServer(t) 154 defer closer() 155 s.XFrameOptions = "" 156 s.ContentSecurityPolicy = "" 157 cancelInformer := test.StartInformer(s.projInformer) 158 defer cancelInformer() 159 lns, err := s.Listen() 160 assert.NoError(t, err) 161 ctx, cancel := context.WithCancel(context.Background()) 162 defer cancel() 163 s.Init(ctx) 164 go s.Run(ctx, lns) 165 defer func() { time.Sleep(3 * time.Second) }() 166 167 err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", s.ListenPort), 10*time.Second) 168 assert.NoError(t, err) 169 170 // Allow server startup 171 time.Sleep(1 * time.Second) 172 173 client := http.Client{} 174 url := fmt.Sprintf("http://127.0.0.1:%d/test.html", s.ListenPort) 175 req, err := http.NewRequest(http.MethodGet, url, nil) 176 assert.NoError(t, err) 177 resp, err := client.Do(req) 178 assert.NoError(t, err) 179 assert.Empty(t, resp.Header.Get("X-Frame-Options")) 180 assert.Empty(t, resp.Header.Get("Content-Security-Policy")) 181 } 182 }