17217: Sign locators in CollectionCreate and Update.
authorTom Clegg <tom@curii.com>
Mon, 30 Aug 2021 14:07:33 +0000 (10:07 -0400)
committerTom Clegg <tom@curii.com>
Mon, 30 Aug 2021 14:07:33 +0000 (10:07 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

lib/controller/localdb/collection.go
lib/controller/localdb/collection_test.go
sdk/go/arvados/api.go

index 414c9267994359d005e91a0ba4aefd1b50ba7811..d81dd812bfe2ca575fa44895dac2fadd23fc6a72 100644 (file)
@@ -48,6 +48,40 @@ func (conn *Conn) CollectionList(ctx context.Context, opts arvados.ListOptions)
        return resp, nil
 }
 
+// CollectionCreate defers to railsProxy for everything except blob
+// signatures.
+func (conn *Conn) CollectionCreate(ctx context.Context, opts arvados.CreateOptions) (arvados.Collection, error) {
+       if len(opts.Select) > 0 {
+               // We need to know IsTrashed and TrashAt to implement
+               // signing properly, even if the caller doesn't want
+               // them.
+               opts.Select = append([]string{"is_trashed", "trash_at"}, opts.Select...)
+       }
+       resp, err := conn.railsProxy.CollectionCreate(ctx, opts)
+       if err != nil {
+               return resp, err
+       }
+       conn.signCollection(ctx, &resp)
+       return resp, nil
+}
+
+// CollectionUpdate defers to railsProxy for everything except blob
+// signatures.
+func (conn *Conn) CollectionUpdate(ctx context.Context, opts arvados.UpdateOptions) (arvados.Collection, error) {
+       if len(opts.Select) > 0 {
+               // We need to know IsTrashed and TrashAt to implement
+               // signing properly, even if the caller doesn't want
+               // them.
+               opts.Select = append([]string{"is_trashed", "trash_at"}, opts.Select...)
+       }
+       resp, err := conn.railsProxy.CollectionUpdate(ctx, opts)
+       if err != nil {
+               return resp, err
+       }
+       conn.signCollection(ctx, &resp)
+       return resp, nil
+}
+
 func (conn *Conn) signCollection(ctx context.Context, coll *arvados.Collection) {
        if coll.IsTrashed || coll.ManifestText == "" || !conn.cluster.Collections.BlobSigning {
                return
index 34c2fa23c0649c02a8e7300a90d38727f6c0b80d..e0de7256a18cd9e3cd862d676a76efd292881b5a 100644 (file)
@@ -82,24 +82,28 @@ func (s *CollectionSuite) TestSignatures(c *check.C) {
                c.Check(lresp.Items[0].UnsignedManifestText, check.Matches, `(?ms).* acbd[^ ]*\+3 0:.*`)
        }
 
-       // early trash date causes lower signature TTL
+       // 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{
+               Select: []string{"uuid", "manifest_text"},
                Attrs: map[string]interface{}{
                        "manifest_text": ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:foo\n",
                        "trash_at":      time.Now().UTC().Add(time.Hour),
                }})
        c.Assert(err, check.IsNil)
+       s.checkSignatureExpiry(c, trashed.ManifestText, time.Hour)
        resp, err = s.localdb.CollectionGet(ctx, 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.CollectionCreate(ctx, arvados.CreateOptions{
+       trashed, err = s.localdb.CollectionUpdate(ctx, arvados.UpdateOptions{
+               UUID: trashed.UUID,
                Attrs: map[string]interface{}{
-                       "manifest_text": ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:foo\n",
-                       "trash_at":      time.Now().UTC().Add(time.Hour * 24 * 365),
+                       "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})
        c.Assert(err, check.IsNil)
        s.checkSignatureExpiry(c, resp.ManifestText, time.Hour*24*7*2)
index a57f2a6838bb2b9cd034ca00b245cae41157cd74..736ace75e72ea68ff2038b911dc3d48965000dd3 100644 (file)
@@ -133,6 +133,7 @@ type CreateOptions struct {
 type UpdateOptions struct {
        UUID             string                 `json:"uuid"`
        Attrs            map[string]interface{} `json:"attrs"`
+       Select           []string               `json:"select"`
        BypassFederation bool                   `json:"bypass_federation"`
 }