github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libpages/config/config_v1_test.go (about) 1 // Copyright 2017 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package config 6 7 import ( 8 "bytes" 9 "context" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestConfigV1Default(t *testing.T) { 17 config := DefaultV1() 18 read, list, 19 possibleRead, possibleList, 20 realm, err := config.GetPermissions("/", nil) 21 require.NoError(t, err) 22 require.True(t, read) 23 require.False(t, list) 24 require.True(t, possibleRead) 25 require.False(t, possibleList) 26 require.Equal(t, "/", realm) 27 } 28 29 func TestConfigV1Invalid(t *testing.T) { 30 err := (&V1{ 31 Common: Common{ 32 Version: Version1Str, 33 }, 34 PerPathConfigs: map[string]PerPathConfigV1{ 35 "/": { 36 WhitelistAdditionalPermissions: map[string]string{ 37 "alice": PermRead, 38 }, 39 }, 40 }, 41 }).EnsureInit() 42 require.Error(t, err) 43 require.IsType(t, ErrUndefinedUsername{}, err) 44 45 err = (&V1{ 46 Common: Common{ 47 Version: Version1Str, 48 }, 49 PerPathConfigs: map[string]PerPathConfigV1{ 50 "/": { 51 AnonymousPermissions: "", 52 }, 53 "": { 54 AnonymousPermissions: PermRead, 55 }, 56 }, 57 }).EnsureInit() 58 require.Error(t, err) 59 require.IsType(t, ErrDuplicatePerPathConfigPath{}, err) 60 61 err = (&V1{ 62 Common: Common{ 63 Version: Version1Str, 64 }, 65 PerPathConfigs: map[string]PerPathConfigV1{ 66 "/foo": { 67 AnonymousPermissions: "", 68 }, 69 "/foo/../foo": { 70 AnonymousPermissions: PermRead, 71 }, 72 }, 73 }).EnsureInit() 74 require.Error(t, err) 75 require.IsType(t, ErrDuplicatePerPathConfigPath{}, err) 76 77 err = (&V1{ 78 Common: Common{ 79 Version: Version1Str, 80 }, 81 PerPathConfigs: map[string]PerPathConfigV1{ 82 "/": { 83 AnonymousPermissions: "huh?", 84 }, 85 }, 86 }).EnsureInit() 87 require.Error(t, err) 88 require.IsType(t, ErrInvalidPermissions{}, err) 89 } 90 91 func TestConfigV1Full(t *testing.T) { 92 config := V1{ 93 Common: Common{ 94 Version: Version1Str, 95 }, 96 Users: map[string]string{ 97 "alice": generateBcryptPasswordHashForTestOrBust(t, "12345"), 98 "bob": generateSHA256PasswordHashForTestOrBust(t, "54321"), 99 }, 100 PerPathConfigs: map[string]PerPathConfigV1{ 101 "/": { 102 AnonymousPermissions: "read,list", 103 }, 104 "/alice-and-bob": { 105 WhitelistAdditionalPermissions: map[string]string{ 106 "alice": PermReadAndList, 107 "bob": PermRead, 108 }, 109 }, 110 "/bob": { 111 AnonymousPermissions: "", 112 WhitelistAdditionalPermissions: map[string]string{ 113 "bob": PermReadAndList, 114 }, 115 }, 116 "/public": { 117 AnonymousPermissions: PermReadAndList, 118 }, 119 "/public/not-really": { 120 AnonymousPermissions: "", 121 WhitelistAdditionalPermissions: map[string]string{ 122 "alice": PermReadAndList, 123 }, 124 }, 125 "/bob/dir/deep-dir/deep-deep-dir": {}, 126 }, 127 } 128 129 ctx := context.Background() 130 131 authenticated := config.Authenticate(ctx, "alice", "54321") 132 require.False(t, authenticated) 133 authenticated = config.Authenticate(ctx, "bob", "12345") 134 require.False(t, authenticated) 135 authenticated = config.Authenticate(ctx, "alice", "12345") 136 require.True(t, authenticated) 137 authenticated = config.Authenticate(ctx, "bob", "54321") 138 require.True(t, authenticated) 139 140 read, list, possibleRead, possibleList, 141 realm, err := config.GetPermissions("/", nil) 142 require.NoError(t, err) 143 require.True(t, read) 144 require.True(t, list) 145 require.True(t, possibleRead) 146 require.True(t, possibleList) 147 require.Equal(t, "/", realm) 148 read, list, possibleRead, possibleList, 149 realm, err = config.GetPermissions("/", stringPtr("alice")) 150 require.NoError(t, err) 151 require.True(t, read) 152 require.True(t, list) 153 require.True(t, possibleRead) 154 require.True(t, possibleList) 155 require.Equal(t, "/", realm) 156 read, list, possibleRead, possibleList, 157 realm, err = config.GetPermissions("/", stringPtr("bob")) 158 require.NoError(t, err) 159 require.True(t, read) 160 require.True(t, list) 161 require.True(t, possibleRead) 162 require.True(t, possibleList) 163 require.Equal(t, "/", realm) 164 165 read, list, possibleRead, possibleList, 166 realm, err = config.GetPermissions("/alice-and-bob", nil) 167 require.NoError(t, err) 168 require.False(t, read) 169 require.False(t, list) 170 require.True(t, possibleRead) 171 require.True(t, possibleList) 172 require.Equal(t, "/alice-and-bob", realm) 173 read, list, possibleRead, possibleList, 174 realm, err = config.GetPermissions("/alice-and-bob", stringPtr("alice")) 175 require.NoError(t, err) 176 require.True(t, read) 177 require.True(t, list) 178 require.True(t, possibleRead) 179 require.True(t, possibleList) 180 require.Equal(t, "/alice-and-bob", realm) 181 read, list, possibleRead, possibleList, 182 realm, err = config.GetPermissions("/alice-and-bob", stringPtr("bob")) 183 require.NoError(t, err) 184 require.True(t, read) 185 require.False(t, list) 186 require.True(t, possibleRead) 187 require.True(t, possibleList) 188 require.Equal(t, "/alice-and-bob", realm) 189 190 read, list, possibleRead, possibleList, 191 realm, err = config.GetPermissions("/bob", nil) 192 require.NoError(t, err) 193 require.False(t, read) 194 require.False(t, list) 195 require.True(t, possibleRead) 196 require.True(t, possibleList) 197 require.Equal(t, "/bob", realm) 198 read, list, possibleRead, possibleList, 199 realm, err = config.GetPermissions("/bob", stringPtr("alice")) 200 require.NoError(t, err) 201 require.False(t, read) 202 require.False(t, list) 203 require.True(t, possibleRead) 204 require.True(t, possibleList) 205 require.Equal(t, "/bob", realm) 206 read, list, possibleRead, possibleList, 207 realm, err = config.GetPermissions("/bob", stringPtr("bob")) 208 require.NoError(t, err) 209 require.True(t, read) 210 require.True(t, list) 211 require.True(t, possibleRead) 212 require.True(t, possibleList) 213 require.Equal(t, "/bob", realm) 214 215 read, list, possibleRead, possibleList, 216 realm, err = config.GetPermissions("/public", nil) 217 require.NoError(t, err) 218 require.True(t, read) 219 require.True(t, list) 220 require.True(t, possibleRead) 221 require.True(t, possibleList) 222 require.Equal(t, "/public", realm) 223 read, list, possibleRead, possibleList, 224 realm, err = config.GetPermissions("/public", stringPtr("alice")) 225 require.NoError(t, err) 226 require.True(t, read) 227 require.True(t, list) 228 require.True(t, possibleRead) 229 require.True(t, possibleList) 230 require.Equal(t, "/public", realm) 231 read, list, possibleRead, possibleList, 232 realm, err = config.GetPermissions("/public", stringPtr("bob")) 233 require.NoError(t, err) 234 require.True(t, read) 235 require.True(t, list) 236 require.True(t, possibleRead) 237 require.True(t, possibleList) 238 require.Equal(t, "/public", realm) 239 240 read, list, possibleRead, possibleList, 241 realm, err = config.GetPermissions("/public/not-really", nil) 242 require.NoError(t, err) 243 require.False(t, read) 244 require.False(t, list) 245 require.True(t, possibleRead) 246 require.True(t, possibleList) 247 require.Equal(t, "/public/not-really", realm) 248 read, list, possibleRead, possibleList, 249 realm, err = config.GetPermissions("/public/not-really", stringPtr("alice")) 250 require.NoError(t, err) 251 require.True(t, read) 252 require.True(t, list) 253 require.True(t, possibleRead) 254 require.True(t, possibleList) 255 require.Equal(t, "/public/not-really", realm) 256 read, list, possibleRead, possibleList, 257 realm, err = config.GetPermissions("/public/not-really", stringPtr("bob")) 258 require.NoError(t, err) 259 require.False(t, read) 260 require.False(t, list) 261 require.True(t, possibleRead) 262 require.True(t, possibleList) 263 require.Equal(t, "/public/not-really", realm) 264 265 read, list, possibleRead, possibleList, 266 realm, err = config.GetPermissions("/bob/dir", nil) 267 require.NoError(t, err) 268 require.False(t, read) 269 require.False(t, list) 270 require.True(t, possibleRead) 271 require.True(t, possibleList) 272 require.Equal(t, "/bob", realm) 273 read, list, possibleRead, possibleList, 274 realm, err = config.GetPermissions("/bob/dir", stringPtr("alice")) 275 require.NoError(t, err) 276 require.False(t, read) 277 require.False(t, list) 278 require.True(t, possibleRead) 279 require.True(t, possibleList) 280 require.Equal(t, "/bob", realm) 281 read, list, possibleRead, possibleList, 282 realm, err = config.GetPermissions("/bob/dir", stringPtr("bob")) 283 require.NoError(t, err) 284 require.True(t, read) 285 require.True(t, list) 286 require.True(t, possibleRead) 287 require.True(t, possibleList) 288 require.Equal(t, "/bob", realm) 289 290 read, list, possibleRead, possibleList, 291 realm, err = config.GetPermissions("/bob/dir/sub", nil) 292 require.NoError(t, err) 293 require.False(t, read) 294 require.False(t, list) 295 require.True(t, possibleRead) 296 require.True(t, possibleList) 297 require.Equal(t, "/bob", realm) 298 read, list, possibleRead, possibleList, 299 realm, err = config.GetPermissions("/bob/dir/sub", stringPtr("alice")) 300 require.NoError(t, err) 301 require.False(t, read) 302 require.False(t, list) 303 require.True(t, possibleRead) 304 require.True(t, possibleList) 305 require.Equal(t, "/bob", realm) 306 read, list, possibleRead, possibleList, 307 realm, err = config.GetPermissions("/bob/dir/sub", stringPtr("bob")) 308 require.NoError(t, err) 309 require.True(t, read) 310 require.True(t, list) 311 require.True(t, possibleRead) 312 require.True(t, possibleList) 313 require.Equal(t, "/bob", realm) 314 315 read, list, possibleRead, possibleList, 316 realm, err = config.GetPermissions("/bob/dir/deep-dir/deep-deep-dir", nil) 317 require.NoError(t, err) 318 require.False(t, read) 319 require.False(t, list) 320 require.False(t, possibleRead) 321 require.False(t, possibleList) 322 require.Equal(t, "/bob/dir/deep-dir/deep-deep-dir", realm) 323 read, list, possibleRead, possibleList, 324 realm, err = config.GetPermissions("/bob/dir/deep-dir/deep-deep-dir", stringPtr("alice")) 325 require.NoError(t, err) 326 require.False(t, read) 327 require.False(t, list) 328 require.False(t, possibleRead) 329 require.False(t, possibleList) 330 require.Equal(t, "/bob/dir/deep-dir/deep-deep-dir", realm) 331 read, list, possibleRead, possibleList, 332 realm, err = config.GetPermissions("/bob/dir/deep-dir/deep-deep-dir", stringPtr("bob")) 333 require.NoError(t, err) 334 require.False(t, read) 335 require.False(t, list) 336 require.False(t, possibleRead) 337 require.False(t, possibleList) 338 require.Equal(t, "/bob/dir/deep-dir/deep-deep-dir", realm) 339 } 340 341 func TestV1EncodeObjectKeyOrder(t *testing.T) { 342 // We are relying on an undocumented feature of encoding/json where struct 343 // fields are serialized into json with the same order that they are 344 // defined in the struct. If this ever changes in the future, this test 345 // helps us catch it. 346 v1 := DefaultV1() 347 buf := &bytes.Buffer{} 348 err := v1.Encode(buf, false) 349 require.NoError(t, err) 350 const expectedJSON = `{"version":"v1","users":null,` + 351 `"per_path_configs":{"/":{"whitelist_additional_permissions":null,` + 352 `"anonymous_permissions":"read"}}}` 353 require.Equal(t, expectedJSON, strings.TrimSpace(buf.String())) 354 } 355 356 func TestV1DeprecatingACLsField(t *testing.T) { 357 perPathConfigs := map[string]PerPathConfigV1{ 358 "/": { 359 WhitelistAdditionalPermissions: map[string]string{ 360 "alice": PermRead, 361 }, 362 }, 363 } 364 365 configWithDeprecatedACLs := &V1{ 366 Common: Common{ 367 Version: Version1Str, 368 }, 369 Users: map[string]string{ 370 "alice": generateBcryptPasswordHashForTestOrBust(t, "12345"), 371 }, 372 ACLs: perPathConfigs, 373 } 374 err := (configWithDeprecatedACLs).EnsureInit() 375 require.NoError(t, err) 376 require.Nil(t, configWithDeprecatedACLs.ACLs) 377 require.Equal(t, perPathConfigs, configWithDeprecatedACLs.PerPathConfigs) 378 379 err = (&V1{ 380 Common: Common{ 381 Version: Version1Str, 382 }, 383 Users: map[string]string{ 384 "alice": generateBcryptPasswordHashForTestOrBust(t, "12345"), 385 }, 386 ACLs: perPathConfigs, 387 PerPathConfigs: perPathConfigs, 388 }).EnsureInit() 389 require.IsType(t, ErrACLsPerPathConfigsBothPresent{}, err) 390 }