github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/upak_loader_test.go (about)

     1  // Copyright 2016 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  // There are two test files by this name. One in libkb, one in engine.
     5  
     6  package libkb
     7  
     8  import (
     9  	"testing"
    10  	"time"
    11  
    12  	context "golang.org/x/net/context"
    13  
    14  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    15  	"github.com/keybase/clockwork"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestCachedUserLoad(t *testing.T) {
    20  	tc := SetupTest(t, "GetUPAKLoader()", 1)
    21  	defer tc.Cleanup()
    22  
    23  	fakeClock := clockwork.NewFakeClock()
    24  	tc.G.SetClock(fakeClock)
    25  
    26  	// Load t_alice a few different ways
    27  	arg := NewLoadUserArg(tc.G).WithUID(keybase1.UID("295a7eea607af32040647123732bc819"))
    28  	var info CachedUserLoadInfo
    29  	_, _, err := tc.G.GetUPAKLoader().(*CachedUPAKLoader).loadWithInfo(arg, &info, nil, true)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  
    34  	checkLoad := func(upk *keybase1.UserPlusKeysV2AllIncarnations, err error) {
    35  		if err != nil {
    36  			t.Fatal(err)
    37  		}
    38  		if upk == nil {
    39  			t.Fatal("expected a UPK back")
    40  		}
    41  		if upk.Current.Username != "t_alice" {
    42  			t.Fatalf("expected %s but got %s", "t_alice", upk.Current.Username)
    43  		}
    44  	}
    45  	if info.InCache || info.TimedOut || info.StaleVersion || info.LoadedLeaf || !info.LoadedUser {
    46  		t.Fatalf("wrong info: %+v", info)
    47  	}
    48  
    49  	fakeClock.Advance(CachedUserTimeout / 100)
    50  	info = CachedUserLoadInfo{}
    51  	upk, user, err := tc.G.GetUPAKLoader().(*CachedUPAKLoader).loadWithInfo(arg, &info, nil, true)
    52  	checkLoad(upk, err)
    53  	if user != nil {
    54  		t.Fatal("expected no full user load")
    55  	}
    56  
    57  	if !info.InCache || info.TimedOut || info.StaleVersion || info.LoadedLeaf || info.LoadedUser {
    58  		t.Fatalf("wrong info: %+v", info)
    59  	}
    60  
    61  	fakeClock.Advance(2 * CachedUserTimeout)
    62  	info = CachedUserLoadInfo{}
    63  	upk, user, err = tc.G.GetUPAKLoader().(*CachedUPAKLoader).loadWithInfo(arg, &info, nil, true)
    64  	checkLoad(upk, err)
    65  	if user != nil {
    66  		t.Fatal("expected no full user load")
    67  	}
    68  	if !info.InCache || !info.TimedOut || info.StaleVersion || !info.LoadedLeaf || info.LoadedUser {
    69  		t.Fatalf("wrong info: %+v", info)
    70  	}
    71  
    72  	require.True(t, IsUserByUsernameOffline(NewMetaContextForTest(tc), "t_alice"))
    73  	require.False(t, IsUserByUsernameOffline(NewMetaContextForTest(tc), "t_alice_xxx"))
    74  	// This hardcoded user was put into the TestUIDMapper, so it should return a result
    75  	require.True(t, IsUserByUsernameOffline(NewMetaContextForTest(tc), "max"))
    76  }
    77  
    78  func TestCheckKIDForUID(t *testing.T) {
    79  	tc := SetupTest(t, "CheckKIDForUID", 1)
    80  	defer tc.Cleanup()
    81  
    82  	fakeClock := clockwork.NewFakeClock()
    83  	tc.G.SetClock(fakeClock)
    84  
    85  	georgeUID := keybase1.UID("9f9611a4b7920637b1c2a839b2a0e119")
    86  	georgeKIDSibkey := keybase1.KID("01206f31b54690a95a1a60a0d8861c8ec27c322b49a93b475a631ee6a676018bfd140a")
    87  	georgeKIDSubkey := keybase1.KID("0121d6543b431d9d3b7485cf23fd6d9fa719bbc2429141dcc44b94ebf4093c37aa5b0a")
    88  
    89  	// The 't_kb' user's Sibkey for device named 'Computer'
    90  	kbKIDSibkey := keybase1.KID("0120d2156264b9023ca1828a57e6e925cbb48f80e8e701fe036b1dfd50337d10d6db0a")
    91  
    92  	rebeccaUID := keybase1.UID("99337e411d1004050e9e7ee2cf1a6219")
    93  	rebeccaKIDRevoked := keybase1.KID("0120e177772304cd9ec833ceb88eeb6e32a667151d9e4fb09df433a846d05e6c40350a")
    94  
    95  	found, revokedAt, deleted, err := tc.G.GetUPAKLoader().CheckKIDForUID(context.Background(), georgeUID, georgeKIDSibkey)
    96  	if !found || (revokedAt != nil) || deleted || (err != nil) {
    97  		t.Fatalf("bad CheckKIDForUID response")
    98  	}
    99  	found, revokedAt, deleted, err = tc.G.GetUPAKLoader().CheckKIDForUID(context.Background(), georgeUID, georgeKIDSubkey)
   100  	if !found || (revokedAt != nil) || deleted || (err != nil) {
   101  		t.Fatalf("bad CheckKIDForUID response")
   102  	}
   103  	found, revokedAt, deleted, err = tc.G.GetUPAKLoader().CheckKIDForUID(context.Background(), georgeUID, kbKIDSibkey)
   104  	if found || (revokedAt != nil) || deleted || (err != nil) {
   105  		t.Fatalf("bad CheckKIDForUID response")
   106  	}
   107  
   108  	found, revokedAt, deleted, err = tc.G.GetUPAKLoader().CheckKIDForUID(context.Background(), rebeccaUID, rebeccaKIDRevoked)
   109  	if !found || (revokedAt == nil) || deleted || (err != nil) {
   110  		t.Fatalf("bad CheckKIDForUID response")
   111  	}
   112  }
   113  
   114  func TestCacheFallbacks(t *testing.T) {
   115  	tc := SetupTest(t, "LookupUsernameAndDevice", 1)
   116  	defer tc.Cleanup()
   117  
   118  	fakeClock := clockwork.NewFakeClock()
   119  	tc.G.SetClock(fakeClock)
   120  
   121  	test := func() *CachedUserLoadInfo {
   122  		var ret CachedUserLoadInfo
   123  		uid := keybase1.UID("eb72f49f2dde6429e5d78003dae0c919")
   124  		arg := NewLoadUserArg(tc.G).WithUID(uid)
   125  		upk, _, err := tc.G.GetUPAKLoader().(*CachedUPAKLoader).loadWithInfo(arg, &ret, nil, false)
   126  		require.NoError(t, err)
   127  		require.Equal(t, upk.Current.Username, "t_tracy", "tracy was right")
   128  		return &ret
   129  	}
   130  	i := test()
   131  	require.True(t, (!i.InCache && !i.InDiskCache && !i.TimedOut && !i.StaleVersion && !i.LoadedLeaf && i.LoadedUser))
   132  	i = test()
   133  	require.True(t, (i.InCache && !i.InDiskCache && !i.TimedOut && !i.StaleVersion && !i.LoadedLeaf && !i.LoadedUser))
   134  	tc.G.GetUPAKLoader().ClearMemory()
   135  	i = test()
   136  	require.True(t, (!i.InCache && i.InDiskCache && !i.TimedOut && !i.StaleVersion && !i.LoadedLeaf && !i.LoadedUser))
   137  	i = test()
   138  	require.True(t, (i.InCache && !i.InDiskCache && !i.TimedOut && !i.StaleVersion && !i.LoadedLeaf && !i.LoadedUser))
   139  	fakeClock.Advance(10 * time.Hour)
   140  	i = test()
   141  	require.True(t, (i.InCache && !i.InDiskCache && i.TimedOut && !i.StaleVersion && i.LoadedLeaf && !i.LoadedUser))
   142  	tc.G.GetUPAKLoader().ClearMemory()
   143  	i = test()
   144  	require.True(t, (!i.InCache && i.InDiskCache && !i.TimedOut && !i.StaleVersion && !i.LoadedLeaf && !i.LoadedUser))
   145  }
   146  
   147  func TestLookupUsernameAndDevice(t *testing.T) {
   148  	tc := SetupTest(t, "LookupUsernameAndDevice", 1)
   149  	defer tc.Cleanup()
   150  
   151  	fakeClock := clockwork.NewFakeClock()
   152  	tc.G.SetClock(fakeClock)
   153  
   154  	test := func() {
   155  		uid := keybase1.UID("eb72f49f2dde6429e5d78003dae0c919")
   156  		did := keybase1.DeviceID("e5f7f7ca6b6277de4d2c45f57b767f18")
   157  		un, name, typ, err := tc.G.GetUPAKLoader().LookupUsernameAndDevice(context.Background(), uid, did)
   158  		require.NoError(t, err)
   159  		require.Equal(t, un.String(), "t_tracy", "tracy was right")
   160  		require.Equal(t, name, "work", "right device name")
   161  		require.Equal(t, typ, keybase1.DeviceTypeV2_DESKTOP, "right type")
   162  	}
   163  
   164  	for i := 0; i < 2; i++ {
   165  		test()
   166  		test()
   167  		fakeClock.Advance(10 * time.Hour)
   168  		test()
   169  		test()
   170  		tc.G.GetUPAKLoader().ClearMemory()
   171  	}
   172  }
   173  
   174  func TestLookupUID(t *testing.T) {
   175  	tc := SetupTest(t, "LookupUsernameAndDevice", 1)
   176  	defer tc.Cleanup()
   177  
   178  	fakeClock := clockwork.NewFakeClock()
   179  	tc.G.SetClock(fakeClock)
   180  
   181  	test := func() {
   182  		uid := keybase1.UID("eb72f49f2dde6429e5d78003dae0c919")
   183  		un := NewNormalizedUsername("t_tracy")
   184  		uid2, err := tc.G.GetUPAKLoader().LookupUID(context.Background(), un)
   185  		require.NoError(t, err)
   186  		require.Equal(t, uid, uid2)
   187  	}
   188  
   189  	for i := 0; i < 2; i++ {
   190  		test()
   191  		test()
   192  		fakeClock.Advance(10 * time.Hour)
   193  		test()
   194  		test()
   195  		tc.G.GetUPAKLoader().ClearMemory()
   196  	}
   197  }
   198  
   199  func TestLookupUsername(t *testing.T) {
   200  	tc := SetupTest(t, "LookupUsernameAndDevice", 1)
   201  	defer tc.Cleanup()
   202  
   203  	uid := keybase1.UID("eb72f49f2dde6429e5d78003dae0c919")
   204  	un, err := tc.G.GetUPAKLoader().LookupUsername(context.Background(), uid)
   205  	require.NoError(t, err)
   206  	require.Equal(t, un, NewNormalizedUsername("t_tracy"), "tracy came back")
   207  	badUID := keybase1.UID("eb72f49f2dde6429e5d78003dae0b919")
   208  	_, err = tc.G.GetUPAKLoader().LookupUsername(context.Background(), badUID)
   209  	require.Error(t, err)
   210  }
   211  
   212  func TestLoadUPAK2(t *testing.T) {
   213  	tc := SetupTest(t, "LookupUsernameAndDevice", 1)
   214  	defer tc.Cleanup()
   215  
   216  	load := func() {
   217  		uid := keybase1.UID("eb72f49f2dde6429e5d78003dae0c919")
   218  		upak, _, err := tc.G.GetUPAKLoader().LoadV2(NewLoadUserByUIDArg(context.TODO(), tc.G, uid))
   219  		require.NoError(t, err)
   220  		key, ok := upak.Current.DeviceKeys[keybase1.KID("01204fbb0a8ee105c2732155bffd927a6f612b6a36c63c484e6290f6a7ac560a1a780a")]
   221  		require.True(t, ok)
   222  		require.Equal(t, key.Base.Provisioning.SigChainLocation.Seqno, keybase1.Seqno(3))
   223  		require.Equal(t, key.Base.Provisioning.SigChainLocation.SeqType, keybase1.SeqType_PUBLIC)
   224  		require.Nil(t, key.Base.Revocation)
   225  	}
   226  
   227  	load()
   228  	load()
   229  }