1package engine
2
3import (
4	"github.com/keybase/client/go/libkb"
5	keybase1 "github.com/keybase/client/go/protocol/keybase1"
6	"github.com/stretchr/testify/require"
7	"testing"
8)
9
10func TestLoginOneshot(t *testing.T) {
11	tc := SetupEngineTest(t, "login")
12	defer tc.Cleanup()
13	fu := NewFakeUserOrBust(t, "paper")
14	arg := MakeTestSignupEngineRunArg(fu)
15	arg.SkipPaper = false
16	arg.StoreSecret = true
17	loginUI := &paperLoginUI{Username: fu.Username}
18	uis := libkb.UIs{
19		LogUI:    tc.G.UI.GetLogUI(),
20		GPGUI:    &gpgtestui{},
21		SecretUI: fu.NewSecretUI(),
22		LoginUI:  loginUI,
23	}
24	s := NewSignupEngine(tc.G, &arg)
25	m := NewMetaContextForTest(tc).WithUIs(uis)
26	err := RunEngine2(m, s)
27	require.NoError(t, err)
28	require.True(t, len(loginUI.PaperPhrase) > 0)
29
30	assertNumDevicesAndKeys(tc, fu, 2, 4)
31	assertSecretStored(tc, fu.Username)
32	Logout(tc)
33	assertSecretNotStored(tc, fu.Username)
34
35	tc2 := SetupEngineTest(t, "login")
36	defer tc2.Cleanup()
37
38	eng := NewLoginOneshot(tc2.G, keybase1.LoginOneshotArg{
39		Username: fu.NormalizedUsername().String(),
40		PaperKey: loginUI.PaperPhrase,
41	})
42	m = NewMetaContextForTest(tc2)
43	err = RunEngine2(m, eng)
44	require.NoError(t, err)
45	assertNumDevicesAndKeys(tc, fu, 2, 4)
46	err = AssertProvisioned(tc2)
47	require.NoError(t, err)
48
49	// assert paper key generation works
50	uis = libkb.UIs{
51		LogUI:    tc.G.UI.GetLogUI(),
52		LoginUI:  &libkb.TestLoginUI{},
53		SecretUI: fu.NewSecretUI(),
54	}
55	eng2 := NewPaperKey(tc.G)
56	m = m.WithUIs(uis)
57	err = RunEngine2(m, eng2)
58	require.NoError(t, err)
59	require.NotZero(t, len(eng2.Passphrase()))
60
61	testSign(t, tc2)
62	trackAlice(tc2, fu, 2)
63	err = m.LogoutAndDeprovisionIfRevoked()
64	require.NoError(t, err)
65	testSign(t, tc2)
66
67}
68
69// Test for the case that we hit, where a user has a regular keybase service + electron running,
70// and also a bot running on the same machine in oneshot mode. If the oneshot bot logs out,
71// it shouldn't molest the system keystore.  This tests repros and tests that case.
72func TestLoginOneshotNoLogout(t *testing.T) {
73	tc := SetupEngineTest(t, "login")
74	defer tc.Cleanup()
75	fu := NewFakeUserOrBust(t, "paper")
76	arg := MakeTestSignupEngineRunArg(fu)
77	arg.SkipPaper = false
78	arg.StoreSecret = true
79	loginUI := &paperLoginUI{Username: fu.Username}
80	uis := libkb.UIs{
81		LogUI:    tc.G.UI.GetLogUI(),
82		GPGUI:    &gpgtestui{},
83		SecretUI: fu.NewSecretUI(),
84		LoginUI:  loginUI,
85	}
86	s := NewSignupEngine(tc.G, &arg)
87	m := NewMetaContextForTest(tc).WithUIs(uis)
88	err := RunEngine2(m, s)
89	require.NoError(t, err)
90	require.True(t, len(loginUI.PaperPhrase) > 0)
91
92	assertNumDevicesAndKeys(tc, fu, 2, 4)
93	assertSecretStored(tc, fu.Username)
94
95	tc2 := SetupEngineTest(t, "login")
96	tc2.G.Env.Test.DevelName = tc.G.Env.Test.DevelName
97
98	// Assert that tc2 and tc share the same keychain, since they are
99	// on the same machine with the above testing flag override. This only
100	// works on Darwin due to the global nature of the keychain.
101	if libkb.RuntimeGroup() == keybase1.RuntimeGroup_DARWINLIKE {
102		assertSecretStored(tc2, fu.Username)
103	}
104	defer tc2.Cleanup()
105
106	eng := NewLoginOneshot(tc2.G, keybase1.LoginOneshotArg{
107		Username: fu.NormalizedUsername().String(),
108		PaperKey: loginUI.PaperPhrase,
109	})
110	m = NewMetaContextForTest(tc2)
111	err = RunEngine2(m, eng)
112	require.NoError(t, err)
113	assertNumDevicesAndKeys(tc, fu, 2, 4)
114	err = AssertProvisioned(tc2)
115	require.NoError(t, err)
116
117	// This is the crux of the test --- logout in the oneshot regime (via Logout(tc2))
118	// but make sure that the standard install isn't touched. Hence, we need to clear
119	// the memory store to make sure it also doesn't get in the way of the test.
120	tc.G.SecretStore().ClearMem()
121	assertSecretStored(tc, fu.Username)
122	Logout(tc2)
123	tc.G.SecretStore().ClearMem()
124	assertSecretStored(tc, fu.Username)
125}
126