...

Source file src/oras.land/oras-go/pkg/registry/remote/auth/scope_test.go

Documentation: oras.land/oras-go/pkg/registry/remote/auth

     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  }
   451  

View as plain text