github.com/opcr-io/oras-go/v2@v2.0.0-20231122155130-eb4260d8a0ae/registry/remote/auth/challenge_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  
    16  package auth
    17  
    18  import (
    19  	"reflect"
    20  	"testing"
    21  )
    22  
    23  func Test_parseChallenge(t *testing.T) {
    24  	tests := []struct {
    25  		name       string
    26  		header     string
    27  		wantScheme Scheme
    28  		wantParams map[string]string
    29  	}{
    30  		{
    31  			name: "empty header",
    32  		},
    33  		{
    34  			name:       "unknown scheme",
    35  			header:     "foo bar",
    36  			wantScheme: SchemeUnknown,
    37  		},
    38  		{
    39  			name:       "basic challenge",
    40  			header:     `Basic realm="Test Registry"`,
    41  			wantScheme: SchemeBasic,
    42  		},
    43  		{
    44  			name:       "basic challenge with no parameters",
    45  			header:     "Basic",
    46  			wantScheme: SchemeBasic,
    47  		},
    48  		{
    49  			name:       "basic challenge with no parameters but spaces",
    50  			header:     "Basic  ",
    51  			wantScheme: SchemeBasic,
    52  		},
    53  		{
    54  			name:       "bearer challenge",
    55  			header:     `Bearer realm="https://auth.example.io/token",service="registry.example.io",scope="repository:library/hello-world:pull,push"`,
    56  			wantScheme: SchemeBearer,
    57  			wantParams: map[string]string{
    58  				"realm":   "https://auth.example.io/token",
    59  				"service": "registry.example.io",
    60  				"scope":   "repository:library/hello-world:pull,push",
    61  			},
    62  		},
    63  		{
    64  			name:       "bearer challenge with multiple scopes",
    65  			header:     `Bearer realm="https://auth.example.io/token",service="registry.example.io",scope="repository:library/alpine:pull,push repository:ubuntu:pull"`,
    66  			wantScheme: SchemeBearer,
    67  			wantParams: map[string]string{
    68  				"realm":   "https://auth.example.io/token",
    69  				"service": "registry.example.io",
    70  				"scope":   "repository:library/alpine:pull,push repository:ubuntu:pull",
    71  			},
    72  		},
    73  		{
    74  			name:       "bearer challenge with no parameters",
    75  			header:     "Bearer",
    76  			wantScheme: SchemeBearer,
    77  		},
    78  		{
    79  			name:       "bearer challenge with no parameters but spaces",
    80  			header:     "Bearer  ",
    81  			wantScheme: SchemeBearer,
    82  		},
    83  		{
    84  			name:       "bearer challenge with white spaces",
    85  			header:     `Bearer realm = "https://auth.example.io/token"   ,service=registry.example.io, scope  ="repository:library/hello-world:pull,push"  `,
    86  			wantScheme: SchemeBearer,
    87  			wantParams: map[string]string{
    88  				"realm":   "https://auth.example.io/token",
    89  				"service": "registry.example.io",
    90  				"scope":   "repository:library/hello-world:pull,push",
    91  			},
    92  		},
    93  		{
    94  			name:       "bad bearer challenge (incomplete parameter with spaces)",
    95  			header:     `Bearer realm="https://auth.example.io/token",service`,
    96  			wantScheme: SchemeBearer,
    97  			wantParams: map[string]string{
    98  				"realm": "https://auth.example.io/token",
    99  			},
   100  		},
   101  		{
   102  			name:       "bad bearer challenge (incomplete parameter with no value)",
   103  			header:     `Bearer realm="https://auth.example.io/token",service=`,
   104  			wantScheme: SchemeBearer,
   105  			wantParams: map[string]string{
   106  				"realm": "https://auth.example.io/token",
   107  			},
   108  		},
   109  		{
   110  			name:       "bad bearer challenge (incomplete parameter with spaces)",
   111  			header:     `Bearer realm="https://auth.example.io/token",service= `,
   112  			wantScheme: SchemeBearer,
   113  			wantParams: map[string]string{
   114  				"realm": "https://auth.example.io/token",
   115  			},
   116  		},
   117  		{
   118  			name:       "bad bearer challenge (incomplete quote)",
   119  			header:     `Bearer realm="https://auth.example.io/token",service="registry`,
   120  			wantScheme: SchemeBearer,
   121  			wantParams: map[string]string{
   122  				"realm": "https://auth.example.io/token",
   123  			},
   124  		},
   125  		{
   126  			name:       "bearer challenge with empty parameter value",
   127  			header:     `Bearer realm="https://auth.example.io/token",empty="",service="registry.example.io",scope="repository:library/hello-world:pull,push"`,
   128  			wantScheme: SchemeBearer,
   129  			wantParams: map[string]string{
   130  				"realm":   "https://auth.example.io/token",
   131  				"empty":   "",
   132  				"service": "registry.example.io",
   133  				"scope":   "repository:library/hello-world:pull,push",
   134  			},
   135  		},
   136  		{
   137  			name:       "bearer challenge with escaping parameter value",
   138  			header:     `Bearer foo="foo\"bar",hello="\"hello world\""`,
   139  			wantScheme: SchemeBearer,
   140  			wantParams: map[string]string{
   141  				"foo":   `foo"bar`,
   142  				"hello": `"hello world"`,
   143  			},
   144  		},
   145  	}
   146  	for _, tt := range tests {
   147  		t.Run(tt.name, func(t *testing.T) {
   148  			gotScheme, gotParams := parseChallenge(tt.header)
   149  			if gotScheme != tt.wantScheme {
   150  				t.Errorf("parseChallenge() gotScheme = %v, want %v", gotScheme, tt.wantScheme)
   151  			}
   152  			if !reflect.DeepEqual(gotParams, tt.wantParams) {
   153  				t.Errorf("parseChallenge() gotParams = %v, want %v", gotParams, tt.wantParams)
   154  			}
   155  		})
   156  	}
   157  }