13146: Projects shared with me WIP
authorPeter Amstutz <pamstutz@veritasgenetics.com>
Thu, 2 Aug 2018 19:35:17 +0000 (15:35 -0400)
committerPeter Amstutz <pamstutz@veritasgenetics.com>
Fri, 7 Sep 2018 14:15:18 +0000 (10:15 -0400)
Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <pamstutz@veritasgenetics.com>

lib/controller/federation.go
lib/controller/handler.go
lib/controller/shared.go [new file with mode: 0644]

index 24b92505316fd04c967bd08317270785b4720a53..c610a70ec7d0e7dbab97917126b7ee4907279199 100644 (file)
@@ -54,6 +54,19 @@ func (h *Handler) proxyRemoteCluster(w http.ResponseWriter, req *http.Request, n
        h.proxy.Do(w, req, urlOut, client)
 }
 
+type CurrentUser struct {
+       Authorization arvados.APIClientAuthorization
+       UUID          string
+}
+
+func (h *Handler) validateAPItoken(req *http.Request, user *CurrentUser) error {
+       db, err := h.db(req)
+       if err != nil {
+               return err
+       }
+       return db.QueryRowContext(req.Context(), `SELECT api_client_authorizations.uuid, users.uuid FROM api_client_authorizations JOIN users on api_client_authorizations.user_id=users.id WHERE api_token=$1 AND (expires_at IS NULL OR expires_at > current_timestamp) LIMIT 1`, user.Authorization.APIToken).Scan(&user.Authorization.UUID, &user.UUID)
+}
+
 // Extract the auth token supplied in req, and replace it with a
 // salted token for the remote cluster.
 func (h *Handler) saltAuthToken(req *http.Request, remote string) error {
@@ -82,20 +95,16 @@ func (h *Handler) saltAuthToken(req *http.Request, remote string) error {
                // If the token exists in our own database, salt it
                // for the remote. Otherwise, assume it was issued by
                // the remote, and pass it through unmodified.
-               db, err := h.db(req)
-               if err != nil {
-                       return err
-               }
-               aca := arvados.APIClientAuthorization{APIToken: creds.Tokens[0]}
-               err = db.QueryRowContext(req.Context(), `SELECT uuid FROM api_client_authorizations WHERE api_token=$1 AND (expires_at IS NULL OR expires_at > current_timestamp) LIMIT 1`, aca.APIToken).Scan(&aca.UUID)
+               currentUser := CurrentUser{Authorization: arvados.APIClientAuthorization{APIToken: creds.Tokens[0]}}
+               err = h.validateAPItoken(req, &currentUser)
                if err == sql.ErrNoRows {
                        // Not ours; pass through unmodified.
-                       token = aca.APIToken
+                       token = currentUser.Authorization.APIToken
                } else if err != nil {
                        return err
                } else {
                        // Found; make V2 version and salt it.
-                       token, err = auth.SaltToken(aca.TokenV2(), remote)
+                       token, err = auth.SaltToken(currentUser.Authorization.TokenV2(), remote)
                        if err != nil {
                                return err
                        }
index 25799aae9ea30d3116469e205c77f927c313172a..caa84a90cd683913a96d4398001a4923f9042d9e 100644 (file)
@@ -68,6 +68,7 @@ func (h *Handler) setup() {
        })
        hs := http.NotFoundHandler()
        hs = prepend(hs, h.proxyRailsAPI)
+       hs = prepend(hs, h.handleGoAPI)
        hs = prepend(hs, h.proxyRemoteCluster)
        mux.Handle("/", hs)
        h.handlerStack = mux
diff --git a/lib/controller/shared.go b/lib/controller/shared.go
new file mode 100644 (file)
index 0000000..a816ef7
--- /dev/null
@@ -0,0 +1,47 @@
+package controller
+
+import (
+       "database/sql"
+       "fmt"
+       "net/http"
+
+       "git.curoverse.com/arvados.git/sdk/go/arvados"
+       "git.curoverse.com/arvados.git/sdk/go/auth"
+       "git.curoverse.com/arvados.git/sdk/go/httpserver"
+)
+
+func (h *Handler) groupsShared(w http.ResponseWriter, req *http.Request, currentUser CurrentUser) {
+       w.Write([]byte(fmt.Sprintf("Hello world %v\n", currentUser.UUID)))
+}
+
+func (h *Handler) handleGoAPI(w http.ResponseWriter, req *http.Request, next http.Handler) {
+       if req.URL.Path != "/arvados/v1/groups/shared" {
+               next.ServeHTTP(w, req)
+               return
+       }
+
+       // Check token and get user UUID
+
+       creds := auth.NewCredentials()
+       creds.LoadTokensFromHTTPRequest(req)
+
+       if len(creds.Tokens) == 0 {
+               httpserver.Error(w, "Not logged in", http.StatusForbidden)
+               return
+       }
+
+       currentUser := CurrentUser{Authorization: arvados.APIClientAuthorization{APIToken: creds.Tokens[0]}}
+       err := h.validateAPItoken(req, &currentUser)
+       if err != nil {
+               if err == sql.ErrNoRows {
+                       httpserver.Error(w, "Not logged in", http.StatusForbidden)
+               } else {
+                       httpserver.Error(w, err.Error(), http.StatusBadRequest)
+               }
+               return
+       }
+
+       // Handle /arvados/v1/groups/shared
+
+       h.groupsShared(w, req, currentUser)
+}