[ARVADOS] updated: 2.1.0-100-gf194bb8b6

Git user git at public.arvados.org
Wed Nov 18 14:31:31 UTC 2020


Summary of changes:
 lib/controller/integration_test.go                 | 84 ++++++++++------------
 .../api/app/models/api_client_authorization.rb     | 27 +++++--
 2 files changed, 61 insertions(+), 50 deletions(-)

       via  f194bb8b667815f3f3fbd01a3d7ba824b05416ed (commit)
       via  b38ba37a3326f00833371b1965b2876d6cd24185 (commit)
      from  1e044ad2fc88020b03430a3b3c32331aaddc9e2d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit f194bb8b667815f3f3fbd01a3d7ba824b05416ed
Author: Tom Clegg <tom at tomclegg.ca>
Date:   Tue Nov 17 15:42:28 2020 -0500

    17106: Improve handling of bare tokens issued by remote clusters.
    
    When caching, use the remote cluster's original token UUID.
    
    When returning the current api_client_authorization record, include
    the secret supplied by the caller, even when only storing the HMAC in
    the database.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at tomclegg.ca>

diff --git a/services/api/app/models/api_client_authorization.rb b/services/api/app/models/api_client_authorization.rb
index 74a4c1efa..1c1c669de 100644
--- a/services/api/app/models/api_client_authorization.rb
+++ b/services/api/app/models/api_client_authorization.rb
@@ -130,6 +130,7 @@ class ApiClientAuthorization < ArvadosModel
 
     token_uuid = ''
     secret = token
+    stored_secret = nil         # ...if different from secret
     optional = nil
 
     case token[0..2]
@@ -206,8 +207,7 @@ class ApiClientAuthorization < ArvadosModel
         # below. If so, we'll stuff the database with hmac instead of
         # the real OIDC token.
         upstream_cluster_id = Rails.configuration.Login.LoginCluster
-        token_uuid = upstream_cluster_id + generate_uuid[5..27]
-        secret = hmac
+        stored_secret = hmac
       else
         return nil
       end
@@ -246,6 +246,23 @@ class ApiClientAuthorization < ArvadosModel
 
     remote_user_prefix = remote_user['uuid'][0..4]
 
+    if token_uuid == ''
+      # Use the same UUID as the remote when caching the token.
+      begin
+        remote_token = SafeJSON.load(
+          clnt.get_content('https://' + host + '/arvados/v1/api_client_authorizations/current',
+                           {'remote' => Rails.configuration.ClusterID},
+                           {'Authorization' => 'Bearer ' + token}))
+        token_uuid = remote_token['uuid']
+        if !token_uuid.match(HasUuid::UUID_REGEX) || token_uuid[0..4] != upstream_cluster_id
+          raise "remote cluster #{upstream_cluster_id} returned invalid token uuid #{token_uuid.inspect}"
+        end
+      rescue => e
+        Rails.logger.warn "error getting remote token details for #{token.inspect}: #{e}"
+        return nil
+      end
+    end
+
     # Clusters can only authenticate for their own users.
     if remote_user_prefix != upstream_cluster_id
       Rails.logger.warn "remote authentication rejected: claimed remote user #{remote_user_prefix} but token was issued by #{upstream_cluster_id}"
@@ -328,11 +345,13 @@ class ApiClientAuthorization < ArvadosModel
         auth.user = user
         auth.api_client_id = 0
       end
+      stored_secret = stored_secret || secret
       auth.update_attributes!(user: user,
-                              api_token: secret,
+                              api_token: stored_secret,
                               api_client_id: 0,
                               expires_at: Time.now + Rails.configuration.Login.RemoteTokenRefresh)
-      Rails.logger.debug "cached remote token #{token_uuid} with secret #{secret} in local db"
+      Rails.logger.debug "cached remote token #{token_uuid} with secret #{stored_secret} in local db"
+      auth.api_token = secret
       return auth
     end
 

commit b38ba37a3326f00833371b1965b2876d6cd24185
Author: Tom Clegg <tom at tomclegg.ca>
Date:   Tue Nov 17 15:42:11 2020 -0500

    17106: Clean up test.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at tomclegg.ca>

diff --git a/lib/controller/integration_test.go b/lib/controller/integration_test.go
index 5c1181b70..6ac8c2e33 100644
--- a/lib/controller/integration_test.go
+++ b/lib/controller/integration_test.go
@@ -294,71 +294,63 @@ func (s *IntegrationSuite) TestS3WithFederatedToken(c *check.C) {
 
 	conn1 := s.conn("z1111")
 	rootctx1, _, _ := s.rootClients("z1111")
-	userctx1, ac1, kc1, _ := s.userClients(rootctx1, c, conn1, "z1111", true)
+	userctx1, ac1, _, _ := s.userClients(rootctx1, c, conn1, "z1111", true)
 	conn3 := s.conn("z3333")
-	_, ac3, kc3 := s.clientsWithToken("z3333", ac1.AuthToken)
-
-	// Create a collection on z1111
-	var coll arvados.Collection
-	fs1, err := coll.FileSystem(ac1, kc1)
-	c.Assert(err, check.IsNil)
-	f, err := fs1.OpenFile("test.txt", os.O_CREATE|os.O_RDWR, 0777)
-	c.Assert(err, check.IsNil)
-	_, err = io.WriteString(f, testText)
-	c.Assert(err, check.IsNil)
-	err = f.Close()
-	c.Assert(err, check.IsNil)
-	mtxt, err := fs1.MarshalManifest(".")
-	c.Assert(err, check.IsNil)
-	coll1, err := conn1.CollectionCreate(userctx1, arvados.CreateOptions{Attrs: map[string]interface{}{
-		"manifest_text": mtxt,
-	}})
-	c.Assert(err, check.IsNil)
 
-	// Create same collection on z3333
-	fs3, err := coll.FileSystem(ac3, kc3)
-	c.Assert(err, check.IsNil)
-	f, err = fs3.OpenFile("test.txt", os.O_CREATE|os.O_RDWR, 0777)
-	c.Assert(err, check.IsNil)
-	_, err = io.WriteString(f, testText)
-	c.Assert(err, check.IsNil)
-	err = f.Close()
-	c.Assert(err, check.IsNil)
-	mtxt, err = fs3.MarshalManifest(".")
-	c.Assert(err, check.IsNil)
-	coll3, err := conn3.CollectionCreate(userctx1, arvados.CreateOptions{Attrs: map[string]interface{}{
-		"manifest_text": mtxt,
-	}})
-	c.Assert(err, check.IsNil)
+	createColl := func(clusterID string) arvados.Collection {
+		_, ac, kc := s.clientsWithToken(clusterID, ac1.AuthToken)
+		var coll arvados.Collection
+		fs, err := coll.FileSystem(ac, kc)
+		c.Assert(err, check.IsNil)
+		f, err := fs.OpenFile("test.txt", os.O_CREATE|os.O_RDWR, 0777)
+		c.Assert(err, check.IsNil)
+		_, err = io.WriteString(f, testText)
+		c.Assert(err, check.IsNil)
+		err = f.Close()
+		c.Assert(err, check.IsNil)
+		mtxt, err := fs.MarshalManifest(".")
+		c.Assert(err, check.IsNil)
+		coll, err = s.conn(clusterID).CollectionCreate(userctx1, arvados.CreateOptions{Attrs: map[string]interface{}{
+			"manifest_text": mtxt,
+		}})
+		c.Assert(err, check.IsNil)
+		return coll
+	}
 
 	for _, trial := range []struct {
-		label string
-		conn  *rpc.Conn
-		coll  arvados.Collection
+		clusterID string // create the collection on this cluster (then use z3333 to access it)
+		token     string
 	}{
-		{"z1111", conn1, coll1},
-		{"z3333", conn3, coll3},
+		// Try the hardest test first: z3333 hasn't seen
+		// z1111's token yet, and we're just passing the
+		// opaque secret part, so z3333 has to guess that it
+		// belongs to z1111.
+		{"z1111", strings.Split(ac1.AuthToken, "/")[2]},
+		{"z3333", strings.Split(ac1.AuthToken, "/")[2]},
+		{"z1111", strings.Replace(ac1.AuthToken, "/", "_", -1)},
+		{"z3333", strings.Replace(ac1.AuthToken, "/", "_", -1)},
 	} {
-		c.Logf("================ %s", trial.label)
-		cfgjson, err := trial.conn.ConfigGet(userctx1)
+		c.Logf("================ %v", trial)
+		coll := createColl(trial.clusterID)
+
+		cfgjson, err := conn3.ConfigGet(userctx1)
 		c.Assert(err, check.IsNil)
 		var cluster arvados.Cluster
 		err = json.Unmarshal(cfgjson, &cluster)
 		c.Assert(err, check.IsNil)
 
 		c.Logf("TokenV2 is %s", ac1.AuthToken)
-		mungedtoken := strings.Replace(ac1.AuthToken, "/", "_", -1)
 		host := cluster.Services.WebDAV.ExternalURL.Host
 		s3args := []string{
 			"--ssl", "--no-check-certificate",
 			"--host=" + host, "--host-bucket=" + host,
-			"--access_key=" + mungedtoken, "--secret_key=" + mungedtoken,
+			"--access_key=" + trial.token, "--secret_key=" + trial.token,
 		}
-		buf, err := exec.Command("s3cmd", append(s3args, "ls", "s3://"+trial.coll.UUID)...).CombinedOutput()
+		buf, err := exec.Command("s3cmd", append(s3args, "ls", "s3://"+coll.UUID)...).CombinedOutput()
 		c.Check(err, check.IsNil)
-		c.Check(string(buf), check.Matches, `.* `+fmt.Sprintf("%d", len(testText))+` +s3://`+trial.coll.UUID+`/test.txt\n`)
+		c.Check(string(buf), check.Matches, `.* `+fmt.Sprintf("%d", len(testText))+` +s3://`+coll.UUID+`/test.txt\n`)
 
-		buf, err = exec.Command("s3cmd", append(s3args, "get", "s3://"+trial.coll.UUID+"/test.txt", c.MkDir()+"/tmpfile")...).CombinedOutput()
+		buf, err = exec.Command("s3cmd", append(s3args, "get", "s3://"+coll.UUID+"/test.txt", c.MkDir()+"/tmpfile")...).CombinedOutput()
 		// Command fails because we don't return Etag header.
 		// c.Check(err, check.IsNil)
 		flen := strconv.Itoa(len(testText))

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list