github.com/nikkelma/oras-project_oras-go@v1.1.1-0.20220201001104-a75f6a419090/pkg/registry/remote/auth/scope_test.go (about) 1 /* 2 Copyright The ORAS Authors. 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 auth 16 17 import ( 18 "context" 19 "reflect" 20 "testing" 21 ) 22 23 func TestScopeRepository(t *testing.T) { 24 tests := []struct { 25 name string 26 repository string 27 actions []string 28 want string 29 }{ 30 { 31 name: "empty repository", 32 actions: []string{ 33 "pull", 34 }, 35 }, 36 { 37 name: "nil actions", 38 repository: "foo", 39 }, 40 { 41 name: "empty actions", 42 repository: "foo", 43 actions: []string{}, 44 }, 45 { 46 name: "empty actions list", 47 repository: "foo", 48 actions: []string{}, 49 }, 50 { 51 name: "empty actions", 52 repository: "foo", 53 actions: []string{ 54 "", 55 }, 56 }, 57 { 58 name: "single action", 59 repository: "foo", 60 actions: []string{ 61 "pull", 62 }, 63 want: "repository:foo:pull", 64 }, 65 { 66 name: "multiple actions", 67 repository: "foo", 68 actions: []string{ 69 "pull", 70 "push", 71 }, 72 want: "repository:foo:pull,push", 73 }, 74 { 75 name: "unordered actions", 76 repository: "foo", 77 actions: []string{ 78 "push", 79 "pull", 80 }, 81 want: "repository:foo:pull,push", 82 }, 83 { 84 name: "duplicated actions", 85 repository: "foo", 86 actions: []string{ 87 "push", 88 "pull", 89 "pull", 90 "delete", 91 "push", 92 }, 93 want: "repository:foo:delete,pull,push", 94 }, 95 } 96 for _, tt := range tests { 97 t.Run(tt.name, func(t *testing.T) { 98 if got := ScopeRepository(tt.repository, tt.actions...); got != tt.want { 99 t.Errorf("ScopeRepository() = %v, want %v", got, tt.want) 100 } 101 }) 102 } 103 } 104 105 func TestWithScopes(t *testing.T) { 106 ctx := context.Background() 107 108 // with single scope 109 want := []string{ 110 "repository:foo:pull", 111 } 112 ctx = WithScopes(ctx, want...) 113 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 114 t.Errorf("GetScopes(WithScopes()) = %v, want %v", got, want) 115 } 116 117 // overwrite scopes 118 want = []string{ 119 "repository:bar:push", 120 } 121 ctx = WithScopes(ctx, want...) 122 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 123 t.Errorf("GetScopes(WithScopes()) = %v, want %v", got, want) 124 } 125 126 // overwrite scopes with de-duplication 127 scopes := []string{ 128 "repository:hello-world:push", 129 "repository:alpine:delete", 130 "repository:hello-world:pull", 131 "repository:alpine:delete", 132 } 133 want = []string{ 134 "repository:alpine:delete", 135 "repository:hello-world:pull,push", 136 } 137 ctx = WithScopes(ctx, scopes...) 138 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 139 t.Errorf("GetScopes(WithScopes()) = %v, want %v", got, want) 140 } 141 142 // clean scopes 143 want = nil 144 ctx = WithScopes(ctx, want...) 145 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 146 t.Errorf("GetScopes(WithScopes()) = %v, want %v", got, want) 147 } 148 } 149 150 func TestAppendScopes(t *testing.T) { 151 ctx := context.Background() 152 153 // append single scope 154 want := []string{ 155 "repository:foo:pull", 156 } 157 ctx = AppendScopes(ctx, want...) 158 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 159 t.Errorf("GetScopes(AppendScopes()) = %v, want %v", got, want) 160 } 161 162 // append scopes with de-duplication 163 scopes := []string{ 164 "repository:hello-world:push", 165 "repository:alpine:delete", 166 "repository:hello-world:pull", 167 "repository:alpine:delete", 168 } 169 want = []string{ 170 "repository:alpine:delete", 171 "repository:foo:pull", 172 "repository:hello-world:pull,push", 173 } 174 ctx = AppendScopes(ctx, scopes...) 175 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 176 t.Errorf("GetScopes(AppendScopes()) = %v, want %v", got, want) 177 } 178 179 // append empty scopes 180 ctx = AppendScopes(ctx) 181 if got := GetScopes(ctx); !reflect.DeepEqual(got, want) { 182 t.Errorf("GetScopes(AppendScopes()) = %v, want %v", got, want) 183 } 184 } 185 186 func TestCleanScopes(t *testing.T) { 187 tests := []struct { 188 name string 189 scopes []string 190 want []string 191 }{ 192 { 193 name: "nil scope", 194 }, 195 { 196 name: "empty scope", 197 scopes: []string{}, 198 }, 199 { 200 name: "single scope", 201 scopes: []string{ 202 "repository:foo:pull", 203 }, 204 want: []string{ 205 "repository:foo:pull", 206 }, 207 }, 208 { 209 name: "single scope with unordered actions", 210 scopes: []string{ 211 "repository:foo:push,pull,delete", 212 }, 213 want: []string{ 214 "repository:foo:delete,pull,push", 215 }, 216 }, 217 { 218 name: "single scope with duplicated actions", 219 scopes: []string{ 220 "repository:foo:push,pull,push,pull,push,push,pull", 221 }, 222 want: []string{ 223 "repository:foo:pull,push", 224 }, 225 }, 226 { 227 name: "single scope with wild cards", 228 scopes: []string{ 229 "repository:foo:pull,*,push", 230 }, 231 want: []string{ 232 "repository:foo:*", 233 }, 234 }, 235 { 236 name: "single scope with no actions", 237 scopes: []string{ 238 "repository:foo:,", 239 }, 240 want: nil, 241 }, 242 { 243 name: "multiple scopes", 244 scopes: []string{ 245 "repository:bar:push", 246 "repository:foo:pull", 247 }, 248 want: []string{ 249 "repository:bar:push", 250 "repository:foo:pull", 251 }, 252 }, 253 { 254 name: "multiple unordered scopes", 255 scopes: []string{ 256 "repository:foo:pull", 257 "repository:bar:push", 258 }, 259 want: []string{ 260 "repository:bar:push", 261 "repository:foo:pull", 262 }, 263 }, 264 { 265 name: "multiple scopes with duplicates", 266 scopes: []string{ 267 "repository:foo:pull", 268 "repository:bar:push", 269 "repository:foo:push", 270 "repository:bar:push,delete,pull", 271 "repository:bar:delete,pull", 272 "repository:foo:pull", 273 "registry:catalog:*", 274 "registry:catalog:pull", 275 }, 276 want: []string{ 277 "registry:catalog:*", 278 "repository:bar:delete,pull,push", 279 "repository:foo:pull,push", 280 }, 281 }, 282 { 283 name: "multiple scopes with no actions", 284 scopes: []string{ 285 "repository:foo:,", 286 "repository:bar:,", 287 }, 288 want: nil, 289 }, 290 { 291 name: "single unknown or invalid scope", 292 scopes: []string{ 293 "unknown", 294 }, 295 want: []string{ 296 "unknown", 297 }, 298 }, 299 { 300 name: "multiple unknown or invalid scopes", 301 scopes: []string{ 302 "repository:foo:pull", 303 "unknown", 304 "invalid:scope", 305 "no:actions:", 306 "repository:foo:push", 307 }, 308 want: []string{ 309 "invalid:scope", 310 "repository:foo:pull,push", 311 "unknown", 312 }, 313 }, 314 } 315 for _, tt := range tests { 316 t.Run(tt.name, func(t *testing.T) { 317 if got := CleanScopes(tt.scopes); !reflect.DeepEqual(got, tt.want) { 318 t.Errorf("CleanScopes() = %v, want %v", got, tt.want) 319 } 320 }) 321 } 322 } 323 324 func Test_cleanActions(t *testing.T) { 325 tests := []struct { 326 name string 327 actions []string 328 want []string 329 }{ 330 { 331 name: "nil action", 332 }, 333 { 334 name: "empty action", 335 actions: []string{}, 336 }, 337 { 338 name: "single action", 339 actions: []string{ 340 "pull", 341 }, 342 want: []string{ 343 "pull", 344 }, 345 }, 346 { 347 name: "single empty action", 348 actions: []string{ 349 "", 350 }, 351 }, 352 { 353 name: "multiple actions", 354 actions: []string{ 355 "pull", 356 "push", 357 }, 358 want: []string{ 359 "pull", 360 "push", 361 }, 362 }, 363 { 364 name: "multiple actions with empty action", 365 actions: []string{ 366 "pull", 367 "", 368 "push", 369 }, 370 want: []string{ 371 "pull", 372 "push", 373 }, 374 }, 375 { 376 name: "multiple actions with all empty action", 377 actions: []string{ 378 "", 379 "", 380 "", 381 }, 382 want: nil, 383 }, 384 { 385 name: "unordered actions", 386 actions: []string{ 387 "push", 388 "pull", 389 "delete", 390 }, 391 want: []string{ 392 "delete", 393 "pull", 394 "push", 395 }, 396 }, 397 { 398 name: "wildcard", 399 actions: []string{ 400 "*", 401 }, 402 want: []string{ 403 "*", 404 }, 405 }, 406 { 407 name: "wildcard at the begining", 408 actions: []string{ 409 "*", 410 "push", 411 "pull", 412 "delete", 413 }, 414 want: []string{ 415 "*", 416 }, 417 }, 418 { 419 name: "wildcard in the middle", 420 actions: []string{ 421 "push", 422 "pull", 423 "*", 424 "delete", 425 }, 426 want: []string{ 427 "*", 428 }, 429 }, 430 { 431 name: "wildcard at the end", 432 actions: []string{ 433 "push", 434 "pull", 435 "delete", 436 "*", 437 }, 438 want: []string{ 439 "*", 440 }, 441 }, 442 } 443 for _, tt := range tests { 444 t.Run(tt.name, func(t *testing.T) { 445 if got := cleanActions(tt.actions); !reflect.DeepEqual(got, tt.want) { 446 t.Errorf("cleanActions() = %v, want %v", got, tt.want) 447 } 448 }) 449 } 450 }