github.com/weaviate/weaviate@v1.24.6/usecases/auth/authentication/composer/token_validation_test.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package composer
    13  
    14  import (
    15  	"fmt"
    16  	"testing"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  	"github.com/weaviate/weaviate/entities/models"
    21  	"github.com/weaviate/weaviate/usecases/config"
    22  )
    23  
    24  func Test_TokenAuthComposer(t *testing.T) {
    25  	type test struct {
    26  		name         string
    27  		token        string
    28  		config       config.Authentication
    29  		oidc         TokenFunc
    30  		apiKey       TokenFunc
    31  		expectErr    bool
    32  		expectErrMsg string
    33  	}
    34  
    35  	tests := []test{
    36  		{
    37  			name: "everything disabled - pass to oidc provider (backward compat)",
    38  			config: config.Authentication{
    39  				OIDC: config.OIDC{
    40  					Enabled: false,
    41  				},
    42  				APIKey: config.APIKey{
    43  					Enabled: false,
    44  				},
    45  			},
    46  			token: "does not matter",
    47  			apiKey: func(t string, s []string) (*models.Principal, error) {
    48  				panic("i should never be called")
    49  			},
    50  			oidc: func(t string, s []string) (*models.Principal, error) {
    51  				return nil, nil
    52  			},
    53  			expectErr: false,
    54  		},
    55  		{
    56  			name: "everything disabled - pass to oidc provider fail",
    57  			config: config.Authentication{
    58  				OIDC: config.OIDC{
    59  					Enabled: false,
    60  				},
    61  				APIKey: config.APIKey{
    62  					Enabled: false,
    63  				},
    64  			},
    65  			token: "does not matter",
    66  			apiKey: func(t string, s []string) (*models.Principal, error) {
    67  				panic("i should never be called")
    68  			},
    69  			oidc: func(t string, s []string) (*models.Principal, error) {
    70  				return nil, fmt.Errorf("oidc says nope!")
    71  			},
    72  			expectErr:    true,
    73  			expectErrMsg: "oidc says nope!",
    74  		},
    75  		{
    76  			name: "only oidc enabled, returns success",
    77  			config: config.Authentication{
    78  				OIDC: config.OIDC{
    79  					Enabled: true,
    80  				},
    81  				APIKey: config.APIKey{
    82  					Enabled: false,
    83  				},
    84  			},
    85  			token: "does not matter",
    86  			apiKey: func(t string, s []string) (*models.Principal, error) {
    87  				panic("i should never be called")
    88  			},
    89  			oidc: func(t string, s []string) (*models.Principal, error) {
    90  				return nil, nil
    91  			},
    92  			expectErr: false,
    93  		},
    94  		{
    95  			name: "only oidc enabled, returns no success",
    96  			config: config.Authentication{
    97  				OIDC: config.OIDC{
    98  					Enabled: true,
    99  				},
   100  				APIKey: config.APIKey{
   101  					Enabled: false,
   102  				},
   103  			},
   104  			token: "does not matter",
   105  			apiKey: func(t string, s []string) (*models.Principal, error) {
   106  				panic("i should never be called")
   107  			},
   108  			oidc: func(t string, s []string) (*models.Principal, error) {
   109  				return nil, fmt.Errorf("thou shalt not pass")
   110  			},
   111  			expectErr:    true,
   112  			expectErrMsg: "thou shalt not pass",
   113  		},
   114  		{
   115  			name: "only apiKey enabled, returns success",
   116  			config: config.Authentication{
   117  				OIDC: config.OIDC{
   118  					Enabled: false,
   119  				},
   120  				APIKey: config.APIKey{
   121  					Enabled: true,
   122  				},
   123  			},
   124  			token: "does not matter",
   125  			apiKey: func(t string, s []string) (*models.Principal, error) {
   126  				return nil, nil
   127  			},
   128  			oidc: func(t string, s []string) (*models.Principal, error) {
   129  				panic("i should never be called")
   130  			},
   131  			expectErr: false,
   132  		},
   133  		{
   134  			name: "only apiKey enabled, returns no success",
   135  			config: config.Authentication{
   136  				OIDC: config.OIDC{
   137  					Enabled: false,
   138  				},
   139  				APIKey: config.APIKey{
   140  					Enabled: true,
   141  				},
   142  			},
   143  			token: "does not matter",
   144  			apiKey: func(t string, s []string) (*models.Principal, error) {
   145  				return nil, fmt.Errorf("you think I let anyone through?")
   146  			},
   147  			oidc: func(t string, s []string) (*models.Principal, error) {
   148  				panic("i should never be called")
   149  			},
   150  			expectErr:    true,
   151  			expectErrMsg: "you think I let anyone through?",
   152  		},
   153  		{
   154  			name: "both an enabled, with an 'obvious' api key",
   155  			config: config.Authentication{
   156  				OIDC: config.OIDC{
   157  					Enabled: true,
   158  				},
   159  				APIKey: config.APIKey{
   160  					Enabled: true,
   161  				},
   162  			},
   163  			token: "does not matter",
   164  			apiKey: func(t string, s []string) (*models.Principal, error) {
   165  				return nil, fmt.Errorf("it's a pretty key, but not good enough")
   166  			},
   167  			oidc: func(t string, s []string) (*models.Principal, error) {
   168  				panic("i should never be called")
   169  			},
   170  			expectErr:    true,
   171  			expectErrMsg: "it's a pretty key, but not good enough",
   172  		},
   173  		{
   174  			name: "both an enabled, empty token",
   175  			config: config.Authentication{
   176  				OIDC: config.OIDC{
   177  					Enabled: true,
   178  				},
   179  				APIKey: config.APIKey{
   180  					Enabled: true,
   181  				},
   182  			},
   183  			token: "",
   184  			apiKey: func(t string, s []string) (*models.Principal, error) {
   185  				return nil, fmt.Errorf("really? an empty one?")
   186  			},
   187  			oidc: func(t string, s []string) (*models.Principal, error) {
   188  				panic("i should never be called")
   189  			},
   190  			expectErr:    true,
   191  			expectErrMsg: "empty one",
   192  		},
   193  		{
   194  			name: "both an enabled, jwt token",
   195  			config: config.Authentication{
   196  				OIDC: config.OIDC{
   197  					Enabled: true,
   198  				},
   199  				APIKey: config.APIKey{
   200  					Enabled: true,
   201  				},
   202  			},
   203  			token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
   204  			apiKey: func(t string, s []string) (*models.Principal, error) {
   205  				panic("i should never be called")
   206  			},
   207  			oidc: func(t string, s []string) (*models.Principal, error) {
   208  				return nil, fmt.Errorf("john doe ... that sounds like a fake name!")
   209  			},
   210  			expectErr:    true,
   211  			expectErrMsg: "john doe",
   212  		},
   213  	}
   214  
   215  	for _, test := range tests {
   216  		t.Run(test.name, func(t *testing.T) {
   217  			v := New(
   218  				test.config,
   219  				fakeValidator{v: test.apiKey},
   220  				fakeValidator{v: test.oidc},
   221  			)
   222  			_, err := v(test.token, nil)
   223  			if test.expectErr {
   224  				require.NotNil(t, err)
   225  				assert.Contains(t, err.Error(), test.expectErrMsg)
   226  				return
   227  			}
   228  
   229  			require.Nil(t, err)
   230  		})
   231  	}
   232  }
   233  
   234  type fakeValidator struct {
   235  	v TokenFunc
   236  }
   237  
   238  func (v fakeValidator) ValidateAndExtract(t string, s []string) (*models.Principal, error) {
   239  	return v.v(t, s)
   240  }