1package engine 2 3import ( 4 "os" 5 "testing" 6 "time" 7 8 "golang.org/x/net/context" 9 10 "github.com/keybase/client/go/libkb" 11 "github.com/keybase/clockwork" 12 "github.com/stretchr/testify/require" 13) 14 15func TestLoginOffline(t *testing.T) { 16 tc := SetupEngineTest(t, "login") 17 defer tc.Cleanup() 18 19 u1 := CreateAndSignupFakeUser(tc, "login") 20 Logout(tc) 21 u1.LoginOrBust(tc) 22 23 // do a upak load to make sure it is cached 24 arg := libkb.NewLoadUserByUIDArg(context.TODO(), tc.G, u1.UID()) 25 _, _, err := tc.G.GetUPAKLoader().Load(arg) 26 require.NoError(t, err) 27 28 // Simulate restarting the service by wiping out the 29 // passphrase stream cache and cached secret keys 30 clearCaches(tc.G) 31 tc.G.GetUPAKLoader().ClearMemory() 32 33 // set server uri to nonexistent ip so api calls will fail 34 prev := os.Getenv("KEYBASE_SERVER_URI") 35 os.Setenv("KEYBASE_SERVER_URI", "http://127.0.0.127:3333") 36 defer os.Setenv("KEYBASE_SERVER_URI", prev) 37 err = tc.G.ConfigureAPI() 38 require.NoError(t, err) 39 40 eng := NewLoginOffline(tc.G) 41 m := NewMetaContextForTest(tc) 42 if err := RunEngine2(m, eng); err != nil { 43 t.Fatal(err) 44 } 45 uv, deviceID, deviceName, skey, ekey := tc.G.ActiveDevice.AllFields() 46 if uv.IsNil() { 47 t.Errorf("uid is nil, expected it to exist") 48 } 49 if !uv.Uid.Equal(u1.UID()) { 50 t.Errorf("uid: %v, expected %v", uv, u1) 51 } 52 53 if deviceID.IsNil() { 54 t.Errorf("deviceID is nil, expected it to exist") 55 } 56 57 if deviceName != defaultDeviceName { 58 t.Errorf("device name: %q, expected %q", deviceName, defaultDeviceName) 59 } 60 61 if skey == nil { 62 t.Errorf("signing key is nil, expected it to exist") 63 } 64 65 if ekey == nil { 66 t.Errorf("encryption key is nil, expected it to exist") 67 } 68 69 if tc.G.ActiveDevice.Name() != defaultDeviceName { 70 t.Errorf("device name: %q, expected %q", tc.G.ActiveDevice.Name(), defaultDeviceName) 71 } 72} 73 74// Use fake clock to test login offline after significant delay 75// (make sure upak loader won't use network) 76func TestLoginOfflineDelay(t *testing.T) { 77 tc := SetupEngineTest(t, "login") 78 defer tc.Cleanup() 79 80 fakeClock := clockwork.NewFakeClockAt(time.Now()) 81 tc.G.SetClock(fakeClock) 82 83 u1 := CreateAndSignupFakeUser(tc, "login") 84 Logout(tc) 85 u1.LoginOrBust(tc) 86 87 // do a upak load to make sure it is cached 88 arg := libkb.NewLoadUserByUIDArg(context.TODO(), tc.G, u1.UID()) 89 _, _, err := tc.G.GetUPAKLoader().Load(arg) 90 require.NoError(t, err) 91 92 // Simulate restarting the service by wiping out the 93 // passphrase stream cache and cached secret keys 94 clearCaches(tc.G) 95 tc.G.GetUPAKLoader().ClearMemory() 96 97 // set server uri to nonexistent ip so api calls will fail 98 prev := os.Getenv("KEYBASE_SERVER_URI") 99 os.Setenv("KEYBASE_SERVER_URI", "http://127.0.0.127:3333") 100 defer os.Setenv("KEYBASE_SERVER_URI", prev) 101 err = tc.G.ConfigureAPI() 102 require.NoError(t, err) 103 104 // advance the clock past the cache timeout 105 fakeClock.Advance(libkb.CachedUserTimeout * 10) 106 107 eng := NewLoginOffline(tc.G) 108 m := NewMetaContextForTest(tc) 109 if err := RunEngine2(m, eng); err != nil { 110 t.Fatal(err) 111 } 112 uv, deviceID, deviceName, skey, ekey := tc.G.ActiveDevice.AllFields() 113 if uv.IsNil() { 114 t.Errorf("uid is nil, expected it to exist") 115 } 116 if !uv.Uid.Equal(u1.UID()) { 117 t.Errorf("uid: %v, expected %v", uv, u1.UID()) 118 } 119 120 if deviceID.IsNil() { 121 t.Errorf("deviceID is nil, expected it to exist") 122 } 123 124 if deviceName != defaultDeviceName { 125 t.Errorf("device name: %q, expected %q", deviceName, defaultDeviceName) 126 } 127 128 if skey == nil { 129 t.Errorf("signing key is nil, expected it to exist") 130 } 131 132 if ekey == nil { 133 t.Errorf("encryption key is nil, expected it to exist") 134 } 135} 136 137// Login offline with nothing in upak cache for self user. 138func TestLoginOfflineNoUpak(t *testing.T) { 139 tc := SetupEngineTest(t, "login") 140 defer tc.Cleanup() 141 142 u1 := CreateAndSignupFakeUser(tc, "login") 143 Logout(tc) 144 u1.LoginOrBust(tc) 145 146 // Simulate restarting the service by wiping out the 147 // passphrase stream cache and cached secret keys 148 tc.SimulateServiceRestart() 149 tc.G.GetUPAKLoader().ClearMemory() 150 151 // invalidate the cache for uid 152 tc.G.GetUPAKLoader().Invalidate(context.Background(), u1.UID()) 153 154 // set server uri to nonexistent ip so api calls will fail 155 prev := os.Getenv("KEYBASE_SERVER_URI") 156 os.Setenv("KEYBASE_SERVER_URI", "http://127.0.0.127:3333") 157 defer os.Setenv("KEYBASE_SERVER_URI", prev) 158 err := tc.G.ConfigureAPI() 159 require.NoError(t, err) 160 161 eng := NewLoginOffline(tc.G) 162 m := NewMetaContextForTest(tc) 163 err = RunEngine2(m, eng) 164 if err != nil { 165 t.Fatalf("LoginOffline should still work after upak cache invalidation; got %s", err) 166 } 167} 168