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 }