20183: Fixup auth contexts in tests.
authorTom Clegg <tom@curii.com>
Sun, 5 Mar 2023 04:39:17 +0000 (23:39 -0500)
committerTom Clegg <tom@curii.com>
Sun, 5 Mar 2023 06:05:42 +0000 (01:05 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

13 files changed:
lib/controller/localdb/collection_test.go
lib/controller/localdb/container.go
lib/controller/localdb/container_gateway_test.go
lib/controller/localdb/container_request_test.go
lib/controller/localdb/group_test.go
lib/controller/localdb/link_test.go
lib/controller/localdb/localdb_test.go
lib/controller/localdb/log_activity_test.go
lib/controller/localdb/login_ldap_test.go
lib/controller/localdb/login_oidc_test.go
lib/controller/localdb/login_testuser_test.go
lib/ctrlctx/auth.go
lib/ctrlctx/db.go

index 241dc246fea36ff4084481cfe1e74a05045fb00a..02590b0723165985ab582e95d2aa7a342850ba68 100644 (file)
@@ -5,7 +5,6 @@
 package localdb
 
 import (
-       "context"
        "io/fs"
        "path/filepath"
        "regexp"
@@ -14,10 +13,10 @@ import (
        "strings"
        "time"
 
+       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/arvadosclient"
        "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        "git.arvados.org/arvados.git/sdk/go/keepclient"
        check "gopkg.in/check.v1"
 )
@@ -30,7 +29,6 @@ type CollectionSuite struct {
 
 func (s *CollectionSuite) TestCollectionCreateAndUpdateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -46,7 +44,7 @@ func (s *CollectionSuite) TestCollectionCreateAndUpdateWithProperties(c *check.C
                c.Log(c.TestName()+" ", tt.name)
 
                // Create with properties
-               coll, err := s.localdb.CollectionCreate(ctx, arvados.CreateOptions{
+               coll, err := s.localdb.CollectionCreate(s.userctx, arvados.CreateOptions{
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
                                "properties": tt.props,
@@ -59,9 +57,9 @@ func (s *CollectionSuite) TestCollectionCreateAndUpdateWithProperties(c *check.C
                }
 
                // Create, then update with properties
-               coll, err = s.localdb.CollectionCreate(ctx, arvados.CreateOptions{})
+               coll, err = s.localdb.CollectionCreate(s.userctx, arvados.CreateOptions{})
                c.Assert(err, check.IsNil)
-               coll, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+               coll, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                        UUID:   coll.UUID,
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
@@ -77,33 +75,31 @@ func (s *CollectionSuite) TestCollectionCreateAndUpdateWithProperties(c *check.C
 }
 
 func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.AdminToken}})
-       foo, err := s.localdb.railsProxy.CollectionCreate(ctx, arvados.CreateOptions{
+       adminctx := ctrlctx.NewWithToken(s.ctx, s.cluster, arvadostest.AdminToken)
+       foo, err := s.localdb.railsProxy.CollectionCreate(adminctx, arvados.CreateOptions{
                Attrs: map[string]interface{}{
                        "owner_uuid":    arvadostest.ActiveUserUUID,
                        "manifest_text": ". acbd18db4cc2f85cedef654fccc4a4d8+3 0:3:foo.txt\n",
                }})
        c.Assert(err, check.IsNil)
-       s.localdb.signCollection(ctx, &foo)
-       foobarbaz, err := s.localdb.railsProxy.CollectionCreate(ctx, arvados.CreateOptions{
+       s.localdb.signCollection(adminctx, &foo)
+       foobarbaz, err := s.localdb.railsProxy.CollectionCreate(adminctx, arvados.CreateOptions{
                Attrs: map[string]interface{}{
                        "owner_uuid":    arvadostest.ActiveUserUUID,
                        "manifest_text": "./foo/bar 73feffa4b7f6bb68e44cf984c85f6e88+3 0:3:baz.txt\n",
                }})
        c.Assert(err, check.IsNil)
-       s.localdb.signCollection(ctx, &foobarbaz)
-       wazqux, err := s.localdb.railsProxy.CollectionCreate(ctx, arvados.CreateOptions{
+       s.localdb.signCollection(adminctx, &foobarbaz)
+       wazqux, err := s.localdb.railsProxy.CollectionCreate(adminctx, arvados.CreateOptions{
                Attrs: map[string]interface{}{
                        "owner_uuid":    arvadostest.ActiveUserUUID,
                        "manifest_text": "./waz d85b1213473c2fd7c2045020a6b9c62b+3 0:3:qux.txt\n",
                }})
        c.Assert(err, check.IsNil)
-       s.localdb.signCollection(ctx, &wazqux)
-
-       ctx = auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
+       s.localdb.signCollection(adminctx, &wazqux)
 
        // Create using content from existing collections
-       dst, err := s.localdb.CollectionCreate(ctx, arvados.CreateOptions{
+       dst, err := s.localdb.CollectionCreate(s.userctx, arvados.CreateOptions{
                ReplaceFiles: map[string]string{
                        "/f": foo.PortableDataHash + "/foo.txt",
                        "/b": foobarbaz.PortableDataHash + "/foo/bar",
@@ -117,7 +113,7 @@ func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
        s.expectFiles(c, dst, "f", "b/baz.txt", "q/waz/qux.txt", "w/qux.txt")
 
        // Delete a file and a directory
-       dst, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+       dst, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                UUID: dst.UUID,
                ReplaceFiles: map[string]string{
                        "/f":     "",
@@ -127,7 +123,7 @@ func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
        s.expectFiles(c, dst, "b/baz.txt", "q/", "w/qux.txt")
 
        // Move and copy content within collection
-       dst, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+       dst, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                UUID: dst.UUID,
                ReplaceFiles: map[string]string{
                        // Note splicing content to /b/corge.txt but
@@ -140,7 +136,7 @@ func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
        s.expectFiles(c, dst, "b/corge.txt", "q/", "w/qux.txt", "quux/corge.txt")
 
        // Remove everything except one file
-       dst, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+       dst, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                UUID: dst.UUID,
                ReplaceFiles: map[string]string{
                        "/":            "",
@@ -150,7 +146,7 @@ func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
        s.expectFiles(c, dst, "b/corge.txt")
 
        // Copy entire collection to root
-       dstcopy, err := s.localdb.CollectionCreate(ctx, arvados.CreateOptions{
+       dstcopy, err := s.localdb.CollectionCreate(s.userctx, arvados.CreateOptions{
                ReplaceFiles: map[string]string{
                        "/": dst.PortableDataHash,
                }})
@@ -188,7 +184,7 @@ func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
                {"/bad": "bad/b"},
                {"/bad": dst.UUID + "/b"},
        } {
-               _, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+               _, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                        UUID:         dst.UUID,
                        ReplaceFiles: badrepl,
                })
@@ -197,7 +193,7 @@ func (s *CollectionSuite) TestCollectionReplaceFiles(c *check.C) {
        }
 
        // Check conflicting replace_files and manifest_text
-       _, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+       _, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                UUID:         dst.UUID,
                ReplaceFiles: map[string]string{"/": ""},
                Attrs: map[string]interface{}{
@@ -251,18 +247,16 @@ func (s *CollectionSuite) expectFiles(c *check.C, coll arvados.Collection, expec
 }
 
 func (s *CollectionSuite) TestSignatures(c *check.C) {
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
-
-       resp, err := s.localdb.CollectionGet(ctx, arvados.GetOptions{UUID: arvadostest.FooCollection})
+       resp, err := s.localdb.CollectionGet(s.userctx, arvados.GetOptions{UUID: arvadostest.FooCollection})
        c.Check(err, check.IsNil)
        c.Check(resp.ManifestText, check.Matches, `(?ms).* acbd[^ ]*\+3\+A[0-9a-f]+@[0-9a-f]+ 0:.*`)
        s.checkSignatureExpiry(c, resp.ManifestText, time.Hour*24*7*2)
 
-       resp, err = s.localdb.CollectionGet(ctx, arvados.GetOptions{UUID: arvadostest.FooCollection, Select: []string{"manifest_text"}})
+       resp, err = s.localdb.CollectionGet(s.userctx, arvados.GetOptions{UUID: arvadostest.FooCollection, Select: []string{"manifest_text"}})
        c.Check(err, check.IsNil)
        c.Check(resp.ManifestText, check.Matches, `(?ms).* acbd[^ ]*\+3\+A[0-9a-f]+@[0-9a-f]+ 0:.*`)
 
-       lresp, err := s.localdb.CollectionList(ctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}}})
+       lresp, err := s.localdb.CollectionList(s.userctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}}})
        c.Check(err, check.IsNil)
        if c.Check(lresp.Items, check.HasLen, 1) {
                c.Check(lresp.Items[0].UUID, check.Equals, arvadostest.FooCollection)
@@ -270,14 +264,14 @@ func (s *CollectionSuite) TestSignatures(c *check.C) {
                c.Check(lresp.Items[0].UnsignedManifestText, check.Equals, "")
        }
 
-       lresp, err = s.localdb.CollectionList(ctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}}, Select: []string{"manifest_text"}})
+       lresp, err = s.localdb.CollectionList(s.userctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}}, Select: []string{"manifest_text"}})
        c.Check(err, check.IsNil)
        if c.Check(lresp.Items, check.HasLen, 1) {
                c.Check(lresp.Items[0].ManifestText, check.Matches, `(?ms).* acbd[^ ]*\+3\+A[0-9a-f]+@[0-9a-f]+ 0:.*`)
                c.Check(lresp.Items[0].UnsignedManifestText, check.Equals, "")
        }
 
-       lresp, err = s.localdb.CollectionList(ctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}}, Select: []string{"unsigned_manifest_text"}})
+       lresp, err = s.localdb.CollectionList(s.userctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}}, Select: []string{"unsigned_manifest_text"}})
        c.Check(err, check.IsNil)
        if c.Check(lresp.Items, check.HasLen, 1) {
                c.Check(lresp.Items[0].ManifestText, check.Equals, "")
@@ -286,7 +280,7 @@ func (s *CollectionSuite) TestSignatures(c *check.C) {
 
        // early trash date causes lower signature TTL (even if
        // trash_at and is_trashed fields are unselected)
-       trashed, err := s.localdb.CollectionCreate(ctx, arvados.CreateOptions{
+       trashed, err := s.localdb.CollectionCreate(s.userctx, arvados.CreateOptions{
                Select: []string{"uuid", "manifest_text"},
                Attrs: map[string]interface{}{
                        "manifest_text": ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:foo\n",
@@ -294,25 +288,25 @@ func (s *CollectionSuite) TestSignatures(c *check.C) {
                }})
        c.Assert(err, check.IsNil)
        s.checkSignatureExpiry(c, trashed.ManifestText, time.Hour)
-       resp, err = s.localdb.CollectionGet(ctx, arvados.GetOptions{UUID: trashed.UUID})
+       resp, err = s.localdb.CollectionGet(s.userctx, arvados.GetOptions{UUID: trashed.UUID})
        c.Assert(err, check.IsNil)
        s.checkSignatureExpiry(c, resp.ManifestText, time.Hour)
 
        // distant future trash date does not cause higher signature TTL
-       trashed, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+       trashed, err = s.localdb.CollectionUpdate(s.userctx, arvados.UpdateOptions{
                UUID: trashed.UUID,
                Attrs: map[string]interface{}{
                        "trash_at": time.Now().UTC().Add(time.Hour * 24 * 365),
                }})
        c.Assert(err, check.IsNil)
        s.checkSignatureExpiry(c, trashed.ManifestText, time.Hour*24*7*2)
-       resp, err = s.localdb.CollectionGet(ctx, arvados.GetOptions{UUID: trashed.UUID})
+       resp, err = s.localdb.CollectionGet(s.userctx, arvados.GetOptions{UUID: trashed.UUID})
        c.Assert(err, check.IsNil)
        s.checkSignatureExpiry(c, resp.ManifestText, time.Hour*24*7*2)
 
        // Make sure groups/contents doesn't return manifest_text with
        // collections (if it did, we'd need to sign it).
-       gresp, err := s.localdb.GroupContents(ctx, arvados.GroupContentsOptions{
+       gresp, err := s.localdb.GroupContents(s.userctx, arvados.GroupContentsOptions{
                Limit:   -1,
                Filters: []arvados.Filter{{"uuid", "=", arvadostest.FooCollection}},
                Select:  []string{"uuid", "manifest_text"},
@@ -337,9 +331,7 @@ func (s *CollectionSuite) checkSignatureExpiry(c *check.C, manifestText string,
 
 func (s *CollectionSuite) TestSignaturesDisabled(c *check.C) {
        s.localdb.cluster.Collections.BlobSigning = false
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
-
-       resp, err := s.localdb.CollectionGet(ctx, arvados.GetOptions{UUID: arvadostest.FooCollection})
+       resp, err := s.localdb.CollectionGet(s.userctx, arvados.GetOptions{UUID: arvadostest.FooCollection})
        c.Check(err, check.IsNil)
        c.Check(resp.ManifestText, check.Matches, `(?ms).* acbd[^ +]*\+3 0:.*`)
 }
index 82f3c3b0ae3a02955f22dd67dcbae0de963d5e95..e689cc51cd3904c9d9cda70ea606ae4f7fb0d275 100644 (file)
@@ -10,6 +10,7 @@ import (
        "fmt"
        "time"
 
+       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/ctxlog"
        "github.com/sirupsen/logrus"
@@ -33,6 +34,7 @@ func (conn *Conn) ContainerUpdate(ctx context.Context, opts arvados.UpdateOption
 // after each container update request) corrects any inconsistent
 // container priorities caused by races.
 func (conn *Conn) runContainerPriorityUpdateThread(ctx context.Context) {
+       ctx = ctrlctx.NewWithToken(ctx, conn.cluster, conn.cluster.SystemRootToken)
        log := ctxlog.FromContext(ctx).WithField("worker", "runContainerPriorityUpdateThread")
        ticker := time.NewTicker(5 * time.Minute)
        for {
index ad3136fbcb1527450d89b9e9b6ede6a3ff9d0c8e..ca5e32d071582d1b2d4ce77b86a06dba4aca6438 100644 (file)
@@ -5,7 +5,6 @@
 package localdb
 
 import (
-       "context"
        "crypto/hmac"
        "crypto/sha256"
        "fmt"
@@ -20,9 +19,9 @@ import (
        "git.arvados.org/arvados.git/lib/controller/router"
        "git.arvados.org/arvados.git/lib/controller/rpc"
        "git.arvados.org/arvados.git/lib/crunchrun"
+       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        "git.arvados.org/arvados.git/sdk/go/ctxlog"
        "golang.org/x/crypto/ssh"
        check "gopkg.in/check.v1"
@@ -38,7 +37,6 @@ type ContainerGatewaySuite struct {
 
 func (s *ContainerGatewaySuite) SetUpTest(c *check.C) {
        s.localdbSuite.SetUpTest(c)
-       s.ctx = auth.NewContext(s.ctx, &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        s.ctrUUID = arvadostest.QueuedContainerUUID
 
@@ -68,7 +66,7 @@ func (s *ContainerGatewaySuite) SetUpTest(c *check.C) {
                ArvadosClient: ac,
        }
        c.Assert(s.gw.Start(), check.IsNil)
-       rootctx := auth.NewContext(s.ctx, &auth.Credentials{Tokens: []string{s.cluster.SystemRootToken}})
+       rootctx := ctrlctx.NewWithToken(s.ctx, s.cluster, s.cluster.SystemRootToken)
        // OK if this line fails (because state is already Running
        // from a previous test case) as long as the following line
        // succeeds:
@@ -108,7 +106,7 @@ func (s *ContainerGatewaySuite) TestConfig(c *check.C) {
                c.Logf("trial %#v", trial)
                s.cluster.Containers.ShellAccess.Admin = trial.configAdmin
                s.cluster.Containers.ShellAccess.User = trial.configUser
-               ctx := auth.NewContext(s.ctx, &auth.Credentials{Tokens: []string{trial.sendToken}})
+               ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, trial.sendToken)
                sshconn, err := s.localdb.ContainerSSH(ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
                if trial.errorCode == 0 {
                        if !c.Check(err, check.IsNil) {
@@ -154,7 +152,7 @@ func (s *ContainerGatewaySuite) TestDirectTCP(c *check.C) {
        }
 
        c.Logf("connecting to %s", s.gw.Address)
-       sshconn, err := s.localdb.ContainerSSH(s.ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
+       sshconn, err := s.localdb.ContainerSSH(s.userctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
        c.Assert(err, check.IsNil)
        c.Assert(sshconn.Conn, check.NotNil)
        defer sshconn.Conn.Close()
@@ -192,7 +190,7 @@ func (s *ContainerGatewaySuite) TestDirectTCP(c *check.C) {
 
 func (s *ContainerGatewaySuite) TestConnect(c *check.C) {
        c.Logf("connecting to %s", s.gw.Address)
-       sshconn, err := s.localdb.ContainerSSH(s.ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
+       sshconn, err := s.localdb.ContainerSSH(s.userctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
        c.Assert(err, check.IsNil)
        c.Assert(sshconn.Conn, check.NotNil)
        defer sshconn.Conn.Close()
@@ -223,33 +221,33 @@ func (s *ContainerGatewaySuite) TestConnect(c *check.C) {
        case <-time.After(time.Second):
                c.Fail()
        }
-       ctr, err := s.localdb.ContainerGet(s.ctx, arvados.GetOptions{UUID: s.ctrUUID})
+       ctr, err := s.localdb.ContainerGet(s.userctx, arvados.GetOptions{UUID: s.ctrUUID})
        c.Check(err, check.IsNil)
        c.Check(ctr.InteractiveSessionStarted, check.Equals, true)
 }
 
 func (s *ContainerGatewaySuite) TestConnectFail(c *check.C) {
        c.Log("trying with no token")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{})
+       ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, "")
        _, err := s.localdb.ContainerSSH(ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
        c.Check(err, check.ErrorMatches, `.* 401 .*`)
 
        c.Log("trying with anonymous token")
-       ctx = auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.AnonymousToken}})
+       ctx = ctrlctx.NewWithToken(s.ctx, s.cluster, arvadostest.AnonymousToken)
        _, err = s.localdb.ContainerSSH(ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
        c.Check(err, check.ErrorMatches, `.* 404 .*`)
 }
 
 func (s *ContainerGatewaySuite) TestCreateTunnel(c *check.C) {
        // no AuthSecret
-       conn, err := s.localdb.ContainerGatewayTunnel(s.ctx, arvados.ContainerGatewayTunnelOptions{
+       conn, err := s.localdb.ContainerGatewayTunnel(s.userctx, arvados.ContainerGatewayTunnelOptions{
                UUID: s.ctrUUID,
        })
        c.Check(err, check.ErrorMatches, `authentication error`)
        c.Check(conn.Conn, check.IsNil)
 
        // bogus AuthSecret
-       conn, err = s.localdb.ContainerGatewayTunnel(s.ctx, arvados.ContainerGatewayTunnelOptions{
+       conn, err = s.localdb.ContainerGatewayTunnel(s.userctx, arvados.ContainerGatewayTunnelOptions{
                UUID:       s.ctrUUID,
                AuthSecret: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        })
@@ -257,7 +255,7 @@ func (s *ContainerGatewaySuite) TestCreateTunnel(c *check.C) {
        c.Check(conn.Conn, check.IsNil)
 
        // good AuthSecret
-       conn, err = s.localdb.ContainerGatewayTunnel(s.ctx, arvados.ContainerGatewayTunnelOptions{
+       conn, err = s.localdb.ContainerGatewayTunnel(s.userctx, arvados.ContainerGatewayTunnelOptions{
                UUID:       s.ctrUUID,
                AuthSecret: s.gw.AuthSecret,
        })
@@ -286,7 +284,7 @@ func (s *ContainerGatewaySuite) TestConnectThroughTunnelNoProxyOK(c *check.C) {
 }
 
 func (s *ContainerGatewaySuite) testConnectThroughTunnel(c *check.C, expectErrorMatch string) {
-       rootctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{s.cluster.SystemRootToken}})
+       rootctx := ctrlctx.NewWithToken(s.ctx, s.cluster, s.cluster.SystemRootToken)
        // Until the tunnel starts up, set gateway_address to a value
        // that can't work. We want to ensure the only way we can
        // reach the gateway is through the tunnel.
@@ -321,7 +319,7 @@ func (s *ContainerGatewaySuite) testConnectThroughTunnel(c *check.C, expectError
        c.Assert(err, check.IsNil)
 
        for deadline := time.Now().Add(5 * time.Second); time.Now().Before(deadline); time.Sleep(time.Second / 2) {
-               ctr, err := s.localdb.ContainerGet(s.ctx, arvados.GetOptions{UUID: s.ctrUUID})
+               ctr, err := s.localdb.ContainerGet(s.userctx, arvados.GetOptions{UUID: s.ctrUUID})
                c.Assert(err, check.IsNil)
                c.Check(ctr.InteractiveSessionStarted, check.Equals, false)
                c.Logf("ctr.GatewayAddress == %s", ctr.GatewayAddress)
@@ -332,7 +330,7 @@ func (s *ContainerGatewaySuite) testConnectThroughTunnel(c *check.C, expectError
 
        c.Log("connecting to gateway through tunnel")
        arpc := rpc.NewConn("", &url.URL{Scheme: "https", Host: s.gw.ArvadosClient.APIHost}, true, rpc.PassthroughTokenProvider)
-       sshconn, err := arpc.ContainerSSH(s.ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
+       sshconn, err := arpc.ContainerSSH(s.userctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
        if expectErrorMatch != "" {
                c.Check(err, check.ErrorMatches, expectErrorMatch)
                return
@@ -367,7 +365,7 @@ func (s *ContainerGatewaySuite) testConnectThroughTunnel(c *check.C, expectError
        case <-time.After(time.Second):
                c.Fail()
        }
-       ctr, err := s.localdb.ContainerGet(s.ctx, arvados.GetOptions{UUID: s.ctrUUID})
+       ctr, err := s.localdb.ContainerGet(s.userctx, arvados.GetOptions{UUID: s.ctrUUID})
        c.Check(err, check.IsNil)
        c.Check(ctr.InteractiveSessionStarted, check.Equals, true)
 }
index 45b6de453b160aacc441a0f978e69e549c0f478a..571b77f5e3b603bc40cc8be4cd31f451af0bb909 100644 (file)
@@ -5,11 +5,7 @@
 package localdb
 
 import (
-       "context"
-
        "git.arvados.org/arvados.git/sdk/go/arvados"
-       "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        check "gopkg.in/check.v1"
 )
 
@@ -21,7 +17,6 @@ type ContainerRequestSuite struct {
 
 func (s *ContainerRequestSuite) TestCRCreateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -36,7 +31,7 @@ func (s *ContainerRequestSuite) TestCRCreateWithProperties(c *check.C) {
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
 
-               cnt, err := s.localdb.ContainerRequestCreate(ctx, arvados.CreateOptions{
+               cnt, err := s.localdb.ContainerRequestCreate(s.userctx, arvados.CreateOptions{
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
                                "command":         []string{"echo", "foo"},
@@ -67,7 +62,6 @@ func (s *ContainerRequestSuite) TestCRCreateWithProperties(c *check.C) {
 
 func (s *ContainerRequestSuite) TestCRUpdateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -81,7 +75,7 @@ func (s *ContainerRequestSuite) TestCRUpdateWithProperties(c *check.C) {
        }
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
-               cnt, err := s.localdb.ContainerRequestCreate(ctx, arvados.CreateOptions{
+               cnt, err := s.localdb.ContainerRequestCreate(s.userctx, arvados.CreateOptions{
                        Attrs: map[string]interface{}{
                                "command":         []string{"echo", "foo"},
                                "container_image": "arvados/apitestfixture:latest",
@@ -101,7 +95,7 @@ func (s *ContainerRequestSuite) TestCRUpdateWithProperties(c *check.C) {
                        },
                })
                c.Assert(err, check.IsNil)
-               cnt, err = s.localdb.ContainerRequestUpdate(ctx, arvados.UpdateOptions{
+               cnt, err = s.localdb.ContainerRequestUpdate(s.userctx, arvados.UpdateOptions{
                        UUID:   cnt.UUID,
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
index aa44486ff0b31939db5f24c64f4724ce27a4ed8a..7de36e1c58e38b6c5ca7389ab6d75dfd819f7a43 100644 (file)
@@ -5,11 +5,9 @@
 package localdb
 
 import (
-       "context"
-
+       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        check "gopkg.in/check.v1"
 )
 
@@ -21,7 +19,6 @@ type GroupSuite struct {
 
 func (s *GroupSuite) TestGroupCreateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -36,7 +33,7 @@ func (s *GroupSuite) TestGroupCreateWithProperties(c *check.C) {
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
 
-               grp, err := s.localdb.GroupCreate(ctx, arvados.CreateOptions{
+               grp, err := s.localdb.GroupCreate(s.userctx, arvados.CreateOptions{
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
                                "group_class": "project",
@@ -53,7 +50,6 @@ func (s *GroupSuite) TestGroupCreateWithProperties(c *check.C) {
 
 func (s *GroupSuite) TestGroupUpdateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -67,13 +63,13 @@ func (s *GroupSuite) TestGroupUpdateWithProperties(c *check.C) {
        }
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
-               grp, err := s.localdb.GroupCreate(ctx, arvados.CreateOptions{
+               grp, err := s.localdb.GroupCreate(s.userctx, arvados.CreateOptions{
                        Attrs: map[string]interface{}{
                                "group_class": "project",
                        },
                })
                c.Assert(err, check.IsNil)
-               grp, err = s.localdb.GroupUpdate(ctx, arvados.UpdateOptions{
+               grp, err = s.localdb.GroupUpdate(s.userctx, arvados.UpdateOptions{
                        UUID:   grp.UUID,
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
@@ -89,9 +85,9 @@ func (s *GroupSuite) TestGroupUpdateWithProperties(c *check.C) {
 }
 
 func (s *GroupSuite) TestCanWriteCanManageResponses(c *check.C) {
-       ctxUser1 := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
-       ctxUser2 := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.SpectatorToken}})
-       ctxAdmin := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.AdminToken}})
+       ctxUser1 := ctrlctx.NewWithToken(s.ctx, s.cluster, arvadostest.ActiveTokenV2)
+       ctxUser2 := ctrlctx.NewWithToken(s.ctx, s.cluster, arvadostest.SpectatorToken)
+       ctxAdmin := ctrlctx.NewWithToken(s.ctx, s.cluster, arvadostest.AdminToken)
        project, err := s.localdb.GroupCreate(ctxUser1, arvados.CreateOptions{
                Attrs: map[string]interface{}{
                        "group_class": "project",
index 7f0a30af65d01e456d656a04fef9979b66d73113..5d0fe3d6b28b62d0e56881ef8d2c54eea740ed92 100644 (file)
@@ -5,11 +5,8 @@
 package localdb
 
 import (
-       "context"
-
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        check "gopkg.in/check.v1"
 )
 
@@ -21,7 +18,6 @@ type LinkSuite struct {
 
 func (s *LinkSuite) TestLinkCreateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -36,7 +32,7 @@ func (s *LinkSuite) TestLinkCreateWithProperties(c *check.C) {
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
 
-               lnk, err := s.localdb.LinkCreate(ctx, arvados.CreateOptions{
+               lnk, err := s.localdb.LinkCreate(s.userctx, arvados.CreateOptions{
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
                                "link_class": "star",
@@ -55,7 +51,6 @@ func (s *LinkSuite) TestLinkCreateWithProperties(c *check.C) {
 
 func (s *LinkSuite) TestLinkUpdateWithProperties(c *check.C) {
        s.setUpVocabulary(c, "")
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
 
        tests := []struct {
                name    string
@@ -69,7 +64,7 @@ func (s *LinkSuite) TestLinkUpdateWithProperties(c *check.C) {
        }
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
-               lnk, err := s.localdb.LinkCreate(ctx, arvados.CreateOptions{
+               lnk, err := s.localdb.LinkCreate(s.userctx, arvados.CreateOptions{
                        Attrs: map[string]interface{}{
                                "link_class": "star",
                                "tail_uuid":  "zzzzz-j7d0g-publicfavorites",
@@ -77,7 +72,7 @@ func (s *LinkSuite) TestLinkUpdateWithProperties(c *check.C) {
                        },
                })
                c.Assert(err, check.IsNil)
-               lnk, err = s.localdb.LinkUpdate(ctx, arvados.UpdateOptions{
+               lnk, err = s.localdb.LinkUpdate(s.userctx, arvados.UpdateOptions{
                        UUID:   lnk.UUID,
                        Select: []string{"uuid", "properties"},
                        Attrs: map[string]interface{}{
index 3e7c7421cd4a5b48d0c36bd5da426d6089e1f886..e326ae68d6af76ecff16b04631331bc924d136a7 100644 (file)
@@ -6,6 +6,7 @@ package localdb
 
 import (
        "context"
+       "errors"
 
        "git.arvados.org/arvados.git/lib/config"
        "git.arvados.org/arvados.git/lib/controller/rpc"
@@ -24,6 +25,8 @@ type localdbSuite struct {
        db          *sqlx.DB
        dbConnector *ctrlctx.DBConnector
        tx          *sqlx.Tx
+       txFinish    func(*error)
+       userctx     context.Context // uses ActiveUser token
        localdb     *Conn
        railsSpy    *arvadostest.Proxy
 }
@@ -45,19 +48,24 @@ func (s *localdbSuite) SetUpTest(c *check.C) {
        s.dbConnector = &ctrlctx.DBConnector{PostgreSQL: s.cluster.PostgreSQL}
        s.db, err = s.dbConnector.GetDB(s.ctx)
        c.Assert(err, check.IsNil)
+       s.ctx, s.txFinish = ctrlctx.New(s.ctx, s.dbConnector.GetDB)
+       s.tx, err = ctrlctx.CurrentTx(s.ctx)
+       c.Assert(err, check.IsNil)
        s.localdb = NewConn(s.ctx, s.cluster, s.dbConnector.GetDB)
        s.railsSpy = arvadostest.NewProxy(c, s.cluster.Services.RailsAPI)
        *s.localdb.railsProxy = *rpc.NewConn(s.cluster.ClusterID, s.railsSpy.URL, true, rpc.PassthroughTokenProvider)
-
-       s.tx, err = s.db.Beginx()
-       c.Assert(err, check.IsNil)
-       s.ctx = ctrlctx.NewWithTransaction(s.ctx, s.tx)
+       s.userctx = ctrlctx.NewWithToken(s.ctx, s.cluster, arvadostest.ActiveTokenV2)
 }
 
+var errRollbackAfterTest = errors.New("rollback after test")
+
 func (s *localdbSuite) TearDownTest(c *check.C) {
        if s.tx != nil {
                s.tx.Rollback()
        }
+       if s.txFinish != nil {
+               s.txFinish(&errRollbackAfterTest)
+       }
        if s.railsSpy != nil {
                s.railsSpy.Close()
        }
index b52bb162e70b8148ecfcced4a5fb7e0e4503761b..92624e45081a0f7bb0b012a6bc9342f51392a5b3 100644 (file)
@@ -5,16 +5,11 @@
 package localdb
 
 import (
-       "context"
        "database/sql"
        "time"
 
-       "git.arvados.org/arvados.git/lib/controller/api"
-       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
-       "github.com/jmoiron/sqlx"
        check "gopkg.in/check.v1"
 )
 
@@ -58,16 +53,9 @@ func (s *CollectionSuite) TestLogActivity(c *check.C) {
        s.localdb.activeUsersLock.Lock()
        s.localdb.activeUsersReset = starttime
        s.localdb.activeUsersLock.Unlock()
-       wrap := api.ComposeWrappers(
-               ctrlctx.WrapCallsInTransactions(func(ctx context.Context) (*sqlx.DB, error) { return s.db, nil }),
-               ctrlctx.WrapCallsWithAuth(s.cluster))
-       collectionCreate := wrap(func(ctx context.Context, opts interface{}) (interface{}, error) {
-               return s.localdb.CollectionCreate(ctx, opts.(arvados.CreateOptions))
-       })
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
        for i := 0; i < 2; i++ {
                logthreshold := time.Now()
-               _, err := collectionCreate(ctx, arvados.CreateOptions{
+               _, err := s.localdb.CollectionCreate(s.userctx, arvados.CreateOptions{
                        Attrs: map[string]interface{}{
                                "name": "test collection",
                        },
@@ -75,7 +63,7 @@ func (s *CollectionSuite) TestLogActivity(c *check.C) {
                })
                c.Assert(err, check.IsNil)
                var uuid string
-               err = s.db.QueryRowContext(ctx, `select uuid from logs where object_uuid = $1 and event_at > $2`, arvadostest.ActiveUserUUID, logthreshold.UTC()).Scan(&uuid)
+               err = s.db.QueryRowContext(s.ctx, `select uuid from logs where object_uuid = $1 and event_at > $2`, arvadostest.ActiveUserUUID, logthreshold.UTC()).Scan(&uuid)
                if i == 0 {
                        c.Check(err, check.IsNil)
                        c.Check(uuid, check.HasLen, 27)
index 69b7f57801af9bc74886d4408f2f14ea24a969cd..c7d83902250b8bce8671d0388d3aaf745ba94c90 100644 (file)
@@ -10,8 +10,8 @@ import (
        "net/http"
 
        "git.arvados.org/arvados.git/lib/controller/railsproxy"
+       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        "git.arvados.org/arvados.git/sdk/go/ctxlog"
        "github.com/bradleypeabody/godap"
        check "gopkg.in/check.v1"
@@ -84,7 +84,7 @@ func (s *LDAPSuite) TestLoginSuccess(c *check.C) {
        c.Check(resp.UUID, check.Matches, `zzzzz-gj3su-.*`)
        c.Check(resp.Scopes, check.DeepEquals, []string{"all"})
 
-       ctx := auth.NewContext(s.ctx, &auth.Credentials{Tokens: []string{"v2/" + resp.UUID + "/" + resp.APIToken}})
+       ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, "v2/"+resp.UUID+"/"+resp.APIToken)
        user, err := railsproxy.NewConn(s.cluster).UserGetCurrent(ctx, arvados.GetOptions{})
        c.Check(err, check.IsNil)
        c.Check(user.Email, check.Equals, "goodusername@example.com")
index 5088de6bad3295263321bf0dd7e42aa592a0fe45..cf9cf30eca0086cbc18eed565bd1071a4e7cc1c2 100644 (file)
@@ -255,7 +255,7 @@ func (s *OIDCLoginSuite) TestOIDCAuthorizer(c *check.C) {
        cleanup()
        defer cleanup()
 
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{accessToken}})
+       ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, accessToken)
 
        // Check behavior on 5xx/network errors (don't cache) vs 4xx
        // (do cache)
@@ -357,7 +357,7 @@ func (s *OIDCLoginSuite) TestOIDCAuthorizer(c *check.C) {
 
        s.fakeProvider.AccessTokenPayload = map[string]interface{}{"scope": "openid profile foobar"}
        accessToken = s.fakeProvider.ValidAccessToken()
-       ctx = auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{accessToken}})
+       ctx = ctrlctx.NewWithToken(s.ctx, s.cluster, accessToken)
 
        mac = hmac.New(sha256.New, []byte(s.cluster.SystemRootToken))
        io.WriteString(mac, accessToken)
@@ -523,7 +523,7 @@ func (s *OIDCLoginSuite) TestGoogleLogin_Success(c *check.C) {
 
        // Try using the returned Arvados token.
        c.Logf("trying an API call with new token %q", token)
-       ctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{token}})
+       ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, token)
        cl, err := s.localdb.CollectionList(ctx, arvados.ListOptions{Limit: -1})
        c.Check(cl.ItemsAvailable, check.Not(check.Equals), 0)
        c.Check(cl.Items, check.Not(check.HasLen), 0)
@@ -532,7 +532,7 @@ func (s *OIDCLoginSuite) TestGoogleLogin_Success(c *check.C) {
        // Might as well check that bogus tokens aren't accepted.
        badtoken := token + "plussomeboguschars"
        c.Logf("trying an API call with mangled token %q", badtoken)
-       ctx = auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{badtoken}})
+       ctx = ctrlctx.NewWithToken(s.ctx, s.cluster, badtoken)
        cl, err = s.localdb.CollectionList(ctx, arvados.ListOptions{Limit: -1})
        c.Check(cl.Items, check.HasLen, 0)
        c.Check(err, check.NotNil)
index d5d3c2ff1ed8bb869ac90faded2b535873825d94..51dcaab9db5e67e0520e7e411bc310e3c0755e7d 100644 (file)
@@ -7,9 +7,9 @@ package localdb
 import (
        "database/sql"
 
+       "git.arvados.org/arvados.git/lib/ctrlctx"
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/arvadostest"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        check "gopkg.in/check.v1"
 )
 
@@ -91,9 +91,7 @@ func (s *TestUserSuite) TestExpireTokenOnLogout(c *check.C) {
                {"v2/some-fake-uuid/thisdoesntexistasatoken", "", false},
        } {
                c.Logf("=== %#v", trial)
-               ctx := auth.NewContext(s.ctx, &auth.Credentials{
-                       Tokens: []string{trial.requestToken},
-               })
+               ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, trial.requestToken)
 
                var tokenUUID string
                var err error
index f4c472f73f534c4910cb961c63ff0c01af586b26..31746b64cca5c77a9d8aa695c67e0aa16d8f47ba 100644 (file)
@@ -50,6 +50,27 @@ func WrapCallsWithAuth(cluster *arvados.Cluster) func(api.RoutableFunc) api.Rout
        }
 }
 
+// NewWithToken returns a context with the provided auth token.
+//
+// The incoming context must come from WrapCallsInTransactions or
+// NewWithTransaction.
+//
+// Used for attaching system auth to background threads.
+//
+// Also useful for tests, where context doesn't necessarily come from
+// a router that uses WrapCallsWithAuth.
+//
+// The returned context comes with its own token lookup cache, so
+// NewWithToken is not appropriate to use in a per-request code path.
+func NewWithToken(ctx context.Context, cluster *arvados.Cluster, token string) context.Context {
+       ctx = auth.NewContext(ctx, &auth.Credentials{Tokens: []string{token}})
+       return context.WithValue(ctx, contextKeyAuth, &authcontext{
+               authcache: &authcache{},
+               cluster:   cluster,
+               tokens:    []string{token},
+       })
+}
+
 // CurrentAuth returns the arvados.User whose privileges should be
 // used in the given context, and the arvados.APIClientAuthorization
 // the caller presented in order to authenticate the current request.
index b711b3e650cb2f1c19825c71683cc3817b9abd59..d33fd8ab53cfe1525a65329d1a5f0cfa2b9c7214 100644 (file)
@@ -69,7 +69,7 @@ type finishFunc func(*error)
 // commit or rollback the transaction, if any.
 //
 //     func example(ctx context.Context) (err error) {
-//             ctx, finishtx := New(ctx, dber)
+//             ctx, finishtx := New(ctx, getdb)
 //             defer finishtx(&err)
 //             // ...
 //             tx, err := CurrentTx(ctx)