cuelabs.dev/go/oci/ociregistry@v0.0.0-20240906074133-82eb438dd565/ocifilter/select_test.go (about) 1 // Copyright 2024 CUE Labs AG 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ocifilter 16 17 import ( 18 "context" 19 "errors" 20 "strings" 21 "testing" 22 23 "github.com/go-quicktest/qt" 24 "github.com/opencontainers/go-digest" 25 26 "cuelabs.dev/go/oci/ociregistry" 27 "cuelabs.dev/go/oci/ociregistry/ocimem" 28 ) 29 30 func TestAccessCheckerErrorReturn(t *testing.T) { 31 ctx := context.Background() 32 testErr := errors.New("some error") 33 r1 := AccessChecker(ocimem.New(), func(repoName string, access AccessKind) error { 34 qt.Check(t, qt.Equals(repoName, "foo/bar")) 35 qt.Check(t, qt.Equals(access, AccessRead)) 36 return testErr 37 }) 38 _, err := r1.GetTag(ctx, "foo/bar", "t1") 39 qt.Assert(t, qt.ErrorIs(err, testErr)) 40 } 41 42 func TestAccessCheckerAccessRequest(t *testing.T) { 43 assertAccess := func(wantAccess []accessCheck, do func(ctx context.Context, r ociregistry.Interface) error) { 44 testErr := errors.New("some error") 45 var gotAccess []accessCheck 46 r := AccessChecker(&ociregistry.Funcs{ 47 NewError: func(ctx context.Context, methodName, repo string) error { 48 return testErr 49 }, 50 }, func(repoName string, access AccessKind) error { 51 gotAccess = append(gotAccess, accessCheck{repoName, access}) 52 return nil 53 }) 54 err := do(context.Background(), r) 55 qt.Check(t, qt.ErrorIs(err, testErr)) 56 qt.Check(t, qt.DeepEquals(gotAccess, wantAccess)) 57 } 58 assertAccess([]accessCheck{ 59 {"foo/read", AccessRead}, 60 }, func(ctx context.Context, r ociregistry.Interface) error { 61 _, err := r.GetBlob(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 62 return err 63 }) 64 assertAccess([]accessCheck{ 65 {"foo/read", AccessRead}, 66 }, func(ctx context.Context, r ociregistry.Interface) error { 67 rd, err := r.GetBlobRange(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 100, 200) 68 if rd != nil { 69 rd.Close() 70 } 71 return err 72 }) 73 74 assertAccess([]accessCheck{ 75 {"foo/read", AccessRead}, 76 }, func(ctx context.Context, r ociregistry.Interface) error { 77 rd, err := r.GetManifest(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 78 if rd != nil { 79 rd.Close() 80 } 81 return err 82 }) 83 84 assertAccess([]accessCheck{ 85 {"foo/read", AccessRead}, 86 }, func(ctx context.Context, r ociregistry.Interface) error { 87 rd, err := r.GetTag(ctx, "foo/read", "sometag") 88 if rd != nil { 89 rd.Close() 90 } 91 return err 92 }) 93 94 assertAccess([]accessCheck{ 95 {"foo/read", AccessRead}, 96 }, func(ctx context.Context, r ociregistry.Interface) error { 97 _, err := r.ResolveBlob(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 98 return err 99 }) 100 101 assertAccess([]accessCheck{ 102 {"foo/read", AccessRead}, 103 }, func(ctx context.Context, r ociregistry.Interface) error { 104 _, err := r.ResolveManifest(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 105 return err 106 }) 107 108 assertAccess([]accessCheck{ 109 {"foo/read", AccessRead}, 110 }, func(ctx context.Context, r ociregistry.Interface) error { 111 _, err := r.ResolveTag(ctx, "foo/read", "sometag") 112 return err 113 }) 114 115 assertAccess([]accessCheck{ 116 {"foo/write", AccessWrite}, 117 }, func(ctx context.Context, r ociregistry.Interface) error { 118 _, err := r.PushBlob(ctx, "foo/write", ociregistry.Descriptor{ 119 MediaType: "application/json", 120 Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 121 Size: 3, 122 }, strings.NewReader("foo")) 123 return err 124 }) 125 126 assertAccess([]accessCheck{ 127 {"foo/write", AccessWrite}, 128 }, func(ctx context.Context, r ociregistry.Interface) error { 129 w, err := r.PushBlobChunked(ctx, "foo/write", 0) 130 if err != nil { 131 return err 132 } 133 w.Close() 134 return nil 135 }) 136 137 assertAccess([]accessCheck{ 138 {"foo/write", AccessWrite}, 139 }, func(ctx context.Context, r ociregistry.Interface) error { 140 w, err := r.PushBlobChunkedResume(ctx, "foo/write", "/someid", 3, 0) 141 if err != nil { 142 return err 143 } 144 data := []byte("some data") 145 if _, err := w.Write(data); err != nil { 146 return err 147 } 148 _, err = w.Commit(digest.FromBytes(data)) 149 return err 150 }) 151 152 assertAccess([]accessCheck{ 153 {"foo/read", AccessRead}, 154 {"foo/write", AccessWrite}, 155 }, func(ctx context.Context, r ociregistry.Interface) error { 156 _, err := r.MountBlob(ctx, "foo/read", "foo/write", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 157 return err 158 }) 159 160 assertAccess([]accessCheck{ 161 {"foo/write", AccessWrite}, 162 }, func(ctx context.Context, r ociregistry.Interface) error { 163 _, err := r.PushManifest(ctx, "foo/write", "sometag", []byte("something"), "application/json") 164 return err 165 }) 166 167 assertAccess([]accessCheck{ 168 {"foo/write", AccessDelete}, 169 }, func(ctx context.Context, r ociregistry.Interface) error { 170 return r.DeleteBlob(ctx, "foo/write", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 171 }) 172 173 assertAccess([]accessCheck{ 174 {"foo/write", AccessDelete}, 175 }, func(ctx context.Context, r ociregistry.Interface) error { 176 return r.DeleteManifest(ctx, "foo/write", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 177 }) 178 179 assertAccess([]accessCheck{ 180 {"foo/write", AccessDelete}, 181 }, func(ctx context.Context, r ociregistry.Interface) error { 182 return r.DeleteTag(ctx, "foo/write", "sometag") 183 }) 184 185 assertAccess([]accessCheck{ 186 {"*", AccessList}, 187 }, func(ctx context.Context, r ociregistry.Interface) error { 188 _, err := ociregistry.All(r.Repositories(ctx, "")) 189 return err 190 }) 191 192 assertAccess([]accessCheck{ 193 {"foo/read", AccessList}, 194 }, func(ctx context.Context, r ociregistry.Interface) error { 195 _, err := ociregistry.All(r.Tags(ctx, "foo/read", "")) 196 return err 197 }) 198 199 assertAccess([]accessCheck{ 200 {"foo/read", AccessList}, 201 }, func(ctx context.Context, r ociregistry.Interface) error { 202 _, err := ociregistry.All(r.Referrers(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "")) 203 return err 204 }) 205 } 206 207 type accessCheck struct { 208 Repo string 209 Check AccessKind 210 }