github.com/weaviate/weaviate@v1.24.6/usecases/auth/authentication/apikey/client_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 apikey
    13  
    14  import (
    15  	"testing"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  	"github.com/weaviate/weaviate/usecases/config"
    20  )
    21  
    22  func Test_APIKeyClient(t *testing.T) {
    23  	type test struct {
    24  		name               string
    25  		config             config.APIKey
    26  		expectConfigErr    bool
    27  		expectConfigErrMsg string
    28  		validate           func(t *testing.T, c *Client)
    29  	}
    30  
    31  	tests := []test{
    32  		{
    33  			name: "not enabled",
    34  			config: config.APIKey{
    35  				Enabled: false,
    36  			},
    37  			expectConfigErr: false,
    38  		},
    39  		{
    40  			name: "key, but no user",
    41  			config: config.APIKey{
    42  				Enabled:     true,
    43  				AllowedKeys: []string{"secret-key"},
    44  				Users:       []string{},
    45  			},
    46  			expectConfigErr:    true,
    47  			expectConfigErrMsg: "need at least one user",
    48  		},
    49  		{
    50  			name: "zero length key",
    51  			config: config.APIKey{
    52  				Enabled:     true,
    53  				AllowedKeys: []string{""},
    54  				Users:       []string{"gooduser"},
    55  			},
    56  			expectConfigErr:    true,
    57  			expectConfigErrMsg: "keys cannot have length 0",
    58  		},
    59  		{
    60  			name: "user, but no key",
    61  			config: config.APIKey{
    62  				Enabled:     true,
    63  				AllowedKeys: []string{},
    64  				Users:       []string{"johnnyBeAllowed"},
    65  			},
    66  			expectConfigErr:    true,
    67  			expectConfigErrMsg: "need at least one valid allowed key",
    68  		},
    69  		{
    70  			name: "zero length user",
    71  			config: config.APIKey{
    72  				Enabled:     true,
    73  				AllowedKeys: []string{"secret-key"},
    74  				Users:       []string{""},
    75  			},
    76  			expectConfigErr:    true,
    77  			expectConfigErrMsg: "users cannot have length 0",
    78  		},
    79  		{
    80  			name: "one user, one key",
    81  			config: config.APIKey{
    82  				Enabled:     true,
    83  				AllowedKeys: []string{"secret-key"},
    84  				Users:       []string{"mrRoboto"},
    85  			},
    86  			expectConfigErr: false,
    87  			validate: func(t *testing.T, c *Client) {
    88  				p, err := c.ValidateAndExtract("secret-key", nil)
    89  				require.Nil(t, err)
    90  				assert.Equal(t, "mrRoboto", p.Username)
    91  
    92  				_, err = c.ValidateAndExtract("", nil)
    93  				require.NotNil(t, err)
    94  				_, err = c.ValidateAndExtract("other-key", nil)
    95  				require.NotNil(t, err)
    96  			},
    97  		},
    98  		{
    99  			// this is allowed, this means that all keys point to the same user for
   100  			// authZ purposes
   101  			name: "one user, multiple keys",
   102  			config: config.APIKey{
   103  				Enabled:     true,
   104  				AllowedKeys: []string{"secret-key", "another-secret-key", "third-key"},
   105  				Users:       []string{"jane"},
   106  			},
   107  			expectConfigErr: false,
   108  			validate: func(t *testing.T, c *Client) {
   109  				p, err := c.ValidateAndExtract("secret-key", nil)
   110  				require.Nil(t, err)
   111  				assert.Equal(t, "jane", p.Username)
   112  
   113  				p, err = c.ValidateAndExtract("another-secret-key", nil)
   114  				require.Nil(t, err)
   115  				assert.Equal(t, "jane", p.Username)
   116  
   117  				p, err = c.ValidateAndExtract("third-key", nil)
   118  				require.Nil(t, err)
   119  				assert.Equal(t, "jane", p.Username)
   120  
   121  				_, err = c.ValidateAndExtract("", nil)
   122  				require.NotNil(t, err)
   123  				_, err = c.ValidateAndExtract("other-key", nil)
   124  				require.NotNil(t, err)
   125  			},
   126  		},
   127  		{
   128  			// this is allowed, this means that each key at pos i points to user at
   129  			// pos i for authZ purposes
   130  			name: "multiple user, multiple keys",
   131  			config: config.APIKey{
   132  				Enabled:     true,
   133  				AllowedKeys: []string{"secret-key", "another-secret-key", "third-key"},
   134  				Users:       []string{"jane", "jessica", "jennifer"},
   135  			},
   136  			expectConfigErr: false,
   137  			validate: func(t *testing.T, c *Client) {
   138  				p, err := c.ValidateAndExtract("secret-key", nil)
   139  				require.Nil(t, err)
   140  				assert.Equal(t, "jane", p.Username)
   141  
   142  				p, err = c.ValidateAndExtract("another-secret-key", nil)
   143  				require.Nil(t, err)
   144  				assert.Equal(t, "jessica", p.Username)
   145  
   146  				p, err = c.ValidateAndExtract("third-key", nil)
   147  				require.Nil(t, err)
   148  				assert.Equal(t, "jennifer", p.Username)
   149  
   150  				_, err = c.ValidateAndExtract("", nil)
   151  				require.NotNil(t, err)
   152  				_, err = c.ValidateAndExtract("other-key", nil)
   153  				require.NotNil(t, err)
   154  			},
   155  		},
   156  		{
   157  			// this is invalid, the keys cannot be mapped to the users
   158  			name: "2 users, 3 keys",
   159  			config: config.APIKey{
   160  				Enabled:     true,
   161  				AllowedKeys: []string{"secret-key", "another-secret-key", "third-key"},
   162  				Users:       []string{"jane", "jessica"},
   163  			},
   164  			expectConfigErr:    true,
   165  			expectConfigErrMsg: "length of users and keys must match, alternatively provide single user for all keys",
   166  		},
   167  	}
   168  
   169  	for _, test := range tests {
   170  		t.Run(test.name, func(t *testing.T) {
   171  			c, err := New(config.Config{
   172  				Authentication: config.Authentication{
   173  					APIKey: test.config,
   174  				},
   175  			})
   176  
   177  			if test.expectConfigErr {
   178  				require.NotNil(t, err)
   179  				assert.Contains(t, err.Error(), test.expectConfigErrMsg)
   180  				return
   181  			}
   182  
   183  			if test.validate != nil {
   184  				test.validate(t, c)
   185  			}
   186  		})
   187  	}
   188  }