1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
14 "git.curoverse.com/arvados.git/sdk/go/auth"
15 "git.curoverse.com/arvados.git/sdk/go/httpserver"
18 func remoteContainerRequestCreate(
19 h *genericFederatedRequestHandler,
20 effectiveMethod string,
24 w http.ResponseWriter,
25 req *http.Request) bool {
27 if effectiveMethod != "POST" || uuid != "" || remainder != "" ||
28 *clusterId == "" || *clusterId == h.handler.Cluster.ClusterID {
32 if req.Header.Get("Content-Type") != "application/json" {
33 httpserver.Error(w, "Expected Content-Type: application/json, got "+req.Header.Get("Content-Type"), http.StatusBadRequest)
37 originalBody := req.Body
38 defer originalBody.Close()
39 var request map[string]interface{}
40 err := json.NewDecoder(req.Body).Decode(&request)
42 httpserver.Error(w, err.Error(), http.StatusBadRequest)
46 crString, ok := request["container_request"].(string)
48 var crJson map[string]interface{}
49 err := json.Unmarshal([]byte(crString), &crJson)
51 httpserver.Error(w, err.Error(), http.StatusBadRequest)
55 request["container_request"] = crJson
58 containerRequest, ok := request["container_request"].(map[string]interface{})
60 // Use toplevel object as the container_request object
61 containerRequest = request
64 // If runtime_token is not set, create a new token
65 if _, ok := containerRequest["runtime_token"]; !ok {
66 // First make sure supplied token is valid.
67 creds := auth.NewCredentials()
68 creds.LoadTokensFromHTTPRequest(req)
70 currentUser, err := h.handler.validateAPItoken(req, creds.Tokens[0])
72 httpserver.Error(w, err.Error(), http.StatusForbidden)
76 if len(currentUser.Authorization.Scopes) != 1 || currentUser.Authorization.Scopes[0] != "all" {
77 httpserver.Error(w, "Token scope is not [all]", http.StatusForbidden)
81 // Must be home cluster for this authorization
82 if currentUser.Authorization.UUID[0:5] == h.handler.Cluster.ClusterID {
83 newtok, err := h.handler.createAPItoken(req, currentUser.UUID, nil)
85 httpserver.Error(w, err.Error(), http.StatusForbidden)
88 containerRequest["runtime_token"] = newtok.TokenV2()
92 newbody, err := json.Marshal(request)
93 buf := bytes.NewBuffer(newbody)
94 req.Body = ioutil.NopCloser(buf)
95 req.ContentLength = int64(buf.Len())
96 req.Header.Set("Content-Length", fmt.Sprintf("%v", buf.Len()))
98 resp, err := h.handler.remoteClusterRequest(*clusterId, req)
99 h.handler.proxy.ForwardResponse(w, resp, err)