storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/jwt_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2016, 2017 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"net/http"
    21  	"os"
    22  	"testing"
    23  
    24  	xjwt "storj.io/minio/cmd/jwt"
    25  	"storj.io/minio/pkg/auth"
    26  )
    27  
    28  func testAuthenticate(authType string, t *testing.T) {
    29  	obj, fsDir, err := prepareFS()
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  	defer os.RemoveAll(fsDir)
    34  	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil {
    35  		t.Fatal(err)
    36  	}
    37  
    38  	cred, err := auth.GetNewCredentials()
    39  	if err != nil {
    40  		t.Fatalf("Error getting new credentials: %s", err)
    41  	}
    42  
    43  	globalActiveCred = cred
    44  
    45  	// Define test cases.
    46  	testCases := []struct {
    47  		accessKey   string
    48  		secretKey   string
    49  		expectedErr error
    50  	}{
    51  		// Access key (less than 3 chrs) too small.
    52  		{"u1", cred.SecretKey, auth.ErrInvalidAccessKeyLength},
    53  		// Secret key (less than 8 chrs) too small.
    54  		{cred.AccessKey, "pass", auth.ErrInvalidSecretKeyLength},
    55  		// Authentication error.
    56  		{"myuser", "mypassword", errInvalidAccessKeyID},
    57  		// Authentication error.
    58  		{cred.AccessKey, "mypassword", errAuthentication},
    59  		// Success.
    60  		{cred.AccessKey, cred.SecretKey, nil},
    61  	}
    62  
    63  	// Run tests.
    64  	for _, testCase := range testCases {
    65  		var err error
    66  		if authType == "web" {
    67  			_, err = authenticateWeb(testCase.accessKey, testCase.secretKey)
    68  		} else if authType == "url" {
    69  			_, err = authenticateURL(testCase.accessKey, testCase.secretKey)
    70  		}
    71  
    72  		if testCase.expectedErr != nil {
    73  			if err == nil {
    74  				t.Fatalf("%+v: expected: %s, got: <nil>", testCase, testCase.expectedErr)
    75  			}
    76  			if testCase.expectedErr.Error() != err.Error() {
    77  				t.Fatalf("%+v: expected: %s, got: %s", testCase, testCase.expectedErr, err)
    78  			}
    79  		} else if err != nil {
    80  			t.Fatalf("%+v: expected: <nil>, got: %s", testCase, err)
    81  		}
    82  	}
    83  }
    84  
    85  func TestAuthenticateWeb(t *testing.T) {
    86  	testAuthenticate("web", t)
    87  }
    88  
    89  func TestAuthenticateURL(t *testing.T) {
    90  	testAuthenticate("url", t)
    91  }
    92  
    93  // Tests web request authenticator.
    94  func TestWebRequestAuthenticate(t *testing.T) {
    95  	obj, fsDir, err := prepareFS()
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	defer os.RemoveAll(fsDir)
   100  	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil {
   101  		t.Fatal(err)
   102  	}
   103  
   104  	creds := globalActiveCred
   105  	token, err := getTokenString(creds.AccessKey, creds.SecretKey)
   106  	if err != nil {
   107  		t.Fatalf("unable get token %s", err)
   108  	}
   109  	testCases := []struct {
   110  		req         *http.Request
   111  		expectedErr error
   112  	}{
   113  		// Set valid authorization header.
   114  		{
   115  			req: &http.Request{
   116  				Header: http.Header{
   117  					"Authorization": []string{token},
   118  				},
   119  			},
   120  			expectedErr: nil,
   121  		},
   122  		// No authorization header.
   123  		{
   124  			req: &http.Request{
   125  				Header: http.Header{},
   126  			},
   127  			expectedErr: errNoAuthToken,
   128  		},
   129  		// Invalid authorization token.
   130  		{
   131  			req: &http.Request{
   132  				Header: http.Header{
   133  					"Authorization": []string{"invalid-token"},
   134  				},
   135  			},
   136  			expectedErr: errAuthentication,
   137  		},
   138  	}
   139  
   140  	for i, testCase := range testCases {
   141  		_, _, gotErr := webRequestAuthenticate(testCase.req)
   142  		if testCase.expectedErr != gotErr {
   143  			t.Errorf("Test %d, expected err %s, got %s", i+1, testCase.expectedErr, gotErr)
   144  		}
   145  	}
   146  }
   147  
   148  func BenchmarkParseJWTStandardClaims(b *testing.B) {
   149  	obj, fsDir, err := prepareFS()
   150  	if err != nil {
   151  		b.Fatal(err)
   152  	}
   153  	defer os.RemoveAll(fsDir)
   154  	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil {
   155  		b.Fatal(err)
   156  	}
   157  
   158  	creds := globalActiveCred
   159  	token, err := authenticateNode(creds.AccessKey, creds.SecretKey, "")
   160  	if err != nil {
   161  		b.Fatal(err)
   162  	}
   163  
   164  	b.ResetTimer()
   165  	b.ReportAllocs()
   166  	b.RunParallel(func(pb *testing.PB) {
   167  		for pb.Next() {
   168  			err = xjwt.ParseWithStandardClaims(token, xjwt.NewStandardClaims(), []byte(creds.SecretKey))
   169  			if err != nil {
   170  				b.Fatal(err)
   171  			}
   172  		}
   173  	})
   174  }
   175  
   176  func BenchmarkParseJWTMapClaims(b *testing.B) {
   177  	obj, fsDir, err := prepareFS()
   178  	if err != nil {
   179  		b.Fatal(err)
   180  	}
   181  	defer os.RemoveAll(fsDir)
   182  	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil {
   183  		b.Fatal(err)
   184  	}
   185  
   186  	creds := globalActiveCred
   187  	token, err := authenticateNode(creds.AccessKey, creds.SecretKey, "")
   188  	if err != nil {
   189  		b.Fatal(err)
   190  	}
   191  
   192  	b.ResetTimer()
   193  	b.ReportAllocs()
   194  	b.RunParallel(func(pb *testing.PB) {
   195  		for pb.Next() {
   196  			err = xjwt.ParseWithClaims(token, xjwt.NewMapClaims(), func(*xjwt.MapClaims) ([]byte, error) {
   197  				return []byte(creds.SecretKey), nil
   198  			})
   199  			if err != nil {
   200  				b.Fatal(err)
   201  			}
   202  		}
   203  	})
   204  }
   205  
   206  func BenchmarkAuthenticateNode(b *testing.B) {
   207  	obj, fsDir, err := prepareFS()
   208  	if err != nil {
   209  		b.Fatal(err)
   210  	}
   211  	defer os.RemoveAll(fsDir)
   212  	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil {
   213  		b.Fatal(err)
   214  	}
   215  
   216  	creds := globalActiveCred
   217  	b.ResetTimer()
   218  	b.ReportAllocs()
   219  	for i := 0; i < b.N; i++ {
   220  		authenticateNode(creds.AccessKey, creds.SecretKey, "")
   221  	}
   222  }
   223  
   224  func BenchmarkAuthenticateWeb(b *testing.B) {
   225  	obj, fsDir, err := prepareFS()
   226  	if err != nil {
   227  		b.Fatal(err)
   228  	}
   229  	defer os.RemoveAll(fsDir)
   230  	if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil {
   231  		b.Fatal(err)
   232  	}
   233  
   234  	creds := globalActiveCred
   235  	b.ResetTimer()
   236  	b.ReportAllocs()
   237  	for i := 0; i < b.N; i++ {
   238  		authenticateWeb(creds.AccessKey, creds.SecretKey)
   239  	}
   240  }