X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/365ee0f6bb330046ef276cf8f937bc4c1ae7d69f..24223057a8dd3a03f1c6457287cb12167c6b67ee:/lib/controller/fed_containers.go diff --git a/lib/controller/fed_containers.go b/lib/controller/fed_containers.go index fc627d3faf..c62cea1168 100644 --- a/lib/controller/fed_containers.go +++ b/lib/controller/fed_containers.go @@ -9,11 +9,11 @@ import ( "encoding/json" "fmt" "io/ioutil" - "log" "net/http" + "strings" - "git.curoverse.com/arvados.git/sdk/go/auth" - "git.curoverse.com/arvados.git/sdk/go/httpserver" + "git.arvados.org/arvados.git/sdk/go/auth" + "git.arvados.org/arvados.git/sdk/go/httpserver" ) func remoteContainerRequestCreate( @@ -25,8 +25,28 @@ func remoteContainerRequestCreate( w http.ResponseWriter, req *http.Request) bool { - if effectiveMethod != "POST" || uuid != "" || remainder != "" || - *clusterId == "" || *clusterId == h.handler.Cluster.ClusterID { + if effectiveMethod != "POST" || uuid != "" || remainder != "" { + return false + } + + // First make sure supplied token is valid. + creds := auth.NewCredentials() + creds.LoadTokensFromHTTPRequest(req) + + currentUser, ok, err := h.handler.validateAPItoken(req, creds.Tokens[0]) + if err != nil { + httpserver.Error(w, err.Error(), http.StatusInternalServerError) + return true + } else if !ok { + httpserver.Error(w, "invalid API token", http.StatusForbidden) + return true + } + + if *clusterId == "" || *clusterId == h.handler.Cluster.ClusterID { + // Submitting container request to local cluster. No + // need to set a runtime_token (rails api will create + // one when the container runs) or do a remote cluster + // request. return false } @@ -38,7 +58,7 @@ func remoteContainerRequestCreate( originalBody := req.Body defer originalBody.Close() var request map[string]interface{} - err := json.NewDecoder(req.Body).Decode(&request) + err = json.NewDecoder(req.Body).Decode(&request) if err != nil { httpserver.Error(w, err.Error(), http.StatusBadRequest) return true @@ -64,31 +84,30 @@ func remoteContainerRequestCreate( // If runtime_token is not set, create a new token if _, ok := containerRequest["runtime_token"]; !ok { - log.Printf("ok %v", ok) - - // First make sure supplied token is valid. - creds := auth.NewCredentials() - creds.LoadTokensFromHTTPRequest(req) - - currentUser, err := h.handler.validateAPItoken(req, creds.Tokens[0]) - if err != nil { - httpserver.Error(w, err.Error(), http.StatusForbidden) - return true - } - if len(currentUser.Authorization.Scopes) != 1 || currentUser.Authorization.Scopes[0] != "all" { httpserver.Error(w, "Token scope is not [all]", http.StatusForbidden) return true } - // Must be home cluster for this authorization - if currentUser.Authorization.UUID[0:5] == h.handler.Cluster.ClusterID { + if strings.HasPrefix(currentUser.Authorization.UUID, h.handler.Cluster.ClusterID) { + // Local user, submitting to a remote cluster. + // Create a new time-limited token. newtok, err := h.handler.createAPItoken(req, currentUser.UUID, nil) if err != nil { httpserver.Error(w, err.Error(), http.StatusForbidden) return true } containerRequest["runtime_token"] = newtok.TokenV2() + } else { + // Remote user. Container request will use the + // current token, minus the trailing portion + // (optional container uuid). + sp := strings.Split(creds.Tokens[0], "/") + if len(sp) >= 3 { + containerRequest["runtime_token"] = strings.Join(sp[0:3], "/") + } else { + containerRequest["runtime_token"] = creds.Tokens[0] + } } } @@ -98,10 +117,7 @@ func remoteContainerRequestCreate( req.ContentLength = int64(buf.Len()) req.Header.Set("Content-Length", fmt.Sprintf("%v", buf.Len())) - resp, cancel, err := h.handler.remoteClusterRequest(*clusterId, req) - if cancel != nil { - defer cancel() - } + resp, err := h.handler.remoteClusterRequest(*clusterId, req) h.handler.proxy.ForwardResponse(w, resp, err) return true }