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")
	}
}
Example #2
0
// 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()
}