func TestAuthorizationDelegate(t *testing.T) { checkTest(t) httpClient := &http.Client{} req, err := http.NewRequest("GET", GET_SCOPES_URL, nil) if err != nil { t.Errorf("Failed to create request: %s", err) } // Scope here is intentionally designed to fail. scopes := make([]string, 1) scopes[0] = "noauth" header, err := tc.AuthorizationDelegate(CLIENT_ID, ACCESS_TOKEN, scopes, req) if err != nil { t.Errorf("Failed to create delegating auth %s", err) } req.Header.Add("Authorization", header) resp, err := httpClient.Do(req) if err != nil { t.Errorf("Error issuing request", err) } // Ensure the body is closed after this test. defer resp.Body.Close() if resp.StatusCode != 401 { t.Errorf("Expected delgated request to fail since it has no scopes") } }
// Routes implements the `http.Handler` interface func (self Routes) ServeHTTP(res http.ResponseWriter, req *http.Request) { // A special case for the proxy is returning a bewit signed url. if req.URL.Path[0:6] == "/bewit" { self.signUrl(res, req) return } targetPath, err := tcServices.ConvertPath(req.URL) // Unkown service which we are trying to hit... if err != nil { res.WriteHeader(404) log.Printf("Attempting to use unkown service %s", req.URL.String()) fmt.Fprintf(res, "Unkown taskcluster service: %s", err) return } // Copy method and body over to the proxy request. log.Printf("Proxying %s | %s | %s", req.URL, req.Method, targetPath) proxyReq, err := http.NewRequest(req.Method, targetPath.String(), req.Body) // If we fail to create a request notify the client. if err != nil { res.WriteHeader(500) fmt.Fprintf(res, "Failed to generate proxy request: %s", err) return } // Copy all headers over to the proxy request. for key, _ := range req.Header { // Do not forward connection! if key == "Connection" || key == "Host" { continue } proxyReq.Header.Set(key, req.Header.Get(key)) } // Sign the proxy request with our credentials. auth, err := tc.AuthorizationDelegate( self.ClientId, self.AccessToken, self.Scopes, proxyReq, ) if err != nil { res.WriteHeader(500) fmt.Fprintf(res, "Failed to sign proxy request") return } proxyReq.Header.Set("Authorization", auth) // Issue the proxy request... proxyResp, err := httpClient.Do(proxyReq) if err != nil { res.WriteHeader(500) fmt.Fprintf(res, "Failed during proxy request: %s", err) return } // Map the headers from the proxy back into our proxyResponse headersToSend := res.Header() for key, _ := range proxyResp.Header { headersToSend.Set(key, proxyResp.Header.Get(key)) } headersToSend.Set("X-Taskcluster-Endpoint", targetPath.String()) // Write the proxyResponse headers and status. res.WriteHeader(proxyResp.StatusCode) // Proxy the proxyResponse body from the endpoint to our response. io.Copy(res, proxyResp.Body) proxyResp.Body.Close() }