1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package engine
5
6import (
7	"testing"
8
9	"github.com/keybase/client/go/libkb"
10	"github.com/stretchr/testify/require"
11)
12
13func createFakeUserWithNoKeys(tc libkb.TestContext) (username, passphrase string) {
14	username, email := fakeUser(tc.T, "login")
15	passphrase = fakePassphrase(tc.T)
16	m := NewMetaContextForTest(tc)
17	s := NewSignupEngine(tc.G, nil)
18
19	f := func() error {
20		m = m.WithNewProvisionalLoginContext()
21
22		// going to just run the join step of signup engine
23		if err := s.genPassphraseStream(m, passphrase, false /* randomPW */); err != nil {
24			return err
25		}
26
27		if err := s.join(m, SignupEngineRunArg{
28			Username:   username,
29			Email:      email,
30			InviteCode: libkb.TestInvitationCode,
31			SkipMail:   true,
32		}); err != nil {
33			return err
34		}
35		m = m.CommitProvisionalLogin()
36		return nil
37	}
38	if err := f(); err != nil {
39		tc.T.Fatal(err)
40	}
41
42	return username, passphrase
43}
44
45// createFakeUserWithPGPOnly creates a new fake/testing user, who signed
46// up on the Web site, and used the Web site to generate his/her key.  They
47// used triplesec-encryption and synced their key to the keybase servers.
48func createFakeUserWithPGPOnly(t *testing.T, tc libkb.TestContext) *FakeUser {
49	fu := NewFakeUserOrBust(tc.T, "login")
50
51	secui := &libkb.TestSecretUI{Passphrase: fu.Passphrase}
52	uis := libkb.UIs{
53		GPGUI:    &gpgtestui{},
54		SecretUI: secui,
55		LogUI:    tc.G.UI.GetLogUI(),
56		LoginUI:  &libkb.TestLoginUI{Username: fu.Username},
57	}
58	s := NewSignupEngine(tc.G, nil)
59	m := NewMetaContextForTest(tc).WithUIs(uis)
60
61	// Keep this provisional login around indefinitely, since we're going to need it to
62	// post PGP keys below. This isn't a modern use for our software, but we have this code
63	// to emulate old accounts provisioned by deprecated login paths.
64	m = m.WithNewProvisionalLoginContext()
65	err := s.genPassphraseStream(m, fu.Passphrase, false /* randomPW */)
66	require.NoError(t, err)
67	err = s.join(m, SignupEngineRunArg{
68		Username:   fu.Username,
69		Email:      fu.Email,
70		InviteCode: libkb.TestInvitationCode,
71		SkipMail:   true,
72	})
73	require.NoError(t, err)
74	err = s.fakeLKS(m)
75	require.NoError(t, err)
76	m.Dump()
77
78	// Generate a new test PGP key for the user, and specify the PushSecret
79	// flag so that their triplesec'ed key is pushed to the server.
80	gen := libkb.PGPGenArg{
81		PrimaryBits: 1024,
82		SubkeyBits:  1024,
83	}
84	gen.AddDefaultUID(tc.G)
85	peng := NewPGPKeyImportEngine(tc.G, PGPKeyImportEngineArg{
86		Gen:        &gen,
87		PushSecret: true,
88		Lks:        s.lks,
89		NoSave:     true,
90	})
91
92	err = RunEngine2(m, peng)
93	require.NoError(t, err)
94	fu.User, err = libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m).WithPublicKeyOptional())
95	require.NoError(t, err)
96
97	return fu
98}
99
100// private gpg key not pushed to server
101func createFakeUserWithPGPPubOnly(t *testing.T, tc libkb.TestContext) *FakeUser {
102	fu := NewFakeUserOrBust(t, "login")
103	if err := tc.GenerateGPGKeyring(fu.Email); err != nil {
104		t.Fatal(err)
105	}
106
107	secui := &libkb.TestSecretUI{Passphrase: fu.Passphrase}
108	s := NewSignupEngine(tc.G, nil)
109	uis := libkb.UIs{
110		GPGUI:    &gpgPubOnlyTestUI{},
111		SecretUI: secui,
112		LogUI:    tc.G.UI.GetLogUI(),
113		LoginUI:  &libkb.TestLoginUI{Username: fu.Username},
114	}
115	m := NewMetaContextForTest(tc).WithUIs(uis)
116
117	f := func() error {
118		m = m.WithNewProvisionalLoginContext()
119		if err := s.genPassphraseStream(m, fu.Passphrase, false /* randomPW */); err != nil {
120			return err
121		}
122
123		if err := s.join(m, SignupEngineRunArg{
124			Username:   fu.Username,
125			Email:      fu.Email,
126			InviteCode: libkb.TestInvitationCode,
127			SkipMail:   true,
128		}); err != nil {
129			return err
130		}
131
132		if err := s.fakeLKS(m); err != nil {
133			return err
134		}
135
136		if err := s.addGPG(m, false, false); err != nil {
137			return err
138		}
139		m = m.CommitProvisionalLogin()
140		return nil
141	}
142	if err := f(); err != nil {
143		t.Fatal(err)
144	}
145
146	return fu
147}
148
149// multiple pgp keys
150func createFakeUserWithPGPMult(t *testing.T, tc libkb.TestContext) *FakeUser {
151	fu := NewFakeUserOrBust(t, "login")
152	if err := tc.GenerateGPGKeyring(fu.Email, "xxx@xxx.com"); err != nil {
153		t.Fatal(err)
154	}
155
156	secui := &libkb.TestSecretUI{Passphrase: fu.Passphrase}
157	s := NewSignupEngine(tc.G, nil)
158	uis := libkb.UIs{
159		GPGUI:    &gpgtestui{},
160		SecretUI: secui,
161		LogUI:    tc.G.UI.GetLogUI(),
162		LoginUI:  &libkb.TestLoginUI{Username: fu.Username},
163	}
164	m := NewMetaContextForTest(tc).WithUIs(uis)
165
166	f := func() error {
167		m = m.WithNewProvisionalLoginContext()
168		if err := s.genPassphraseStream(m, fu.Passphrase, false /* randomPW */); err != nil {
169			return err
170		}
171
172		if err := s.join(m, SignupEngineRunArg{
173			Username:   fu.Username,
174			Email:      fu.Email,
175			InviteCode: libkb.TestInvitationCode,
176			SkipMail:   true,
177		}); err != nil {
178			t.Fatal(err)
179		}
180
181		fu.User = s.GetMe()
182
183		// fake the lks:
184		if err := s.fakeLKS(m); err != nil {
185			return err
186		}
187
188		if err := s.addGPG(m, false, false); err != nil {
189			return err
190		}
191
192		// hack the gpg ui to select a different key:
193		m = m.WithGPGUI(&gpgtestui{index: 1})
194		if err := s.addGPG(m, true, false); err != nil {
195			return nil
196		}
197		m = m.CommitProvisionalLogin()
198		return nil
199	}
200
201	if err := f(); err != nil {
202		t.Fatal(err)
203	}
204
205	// now it should have two pgp keys...
206
207	return fu
208}
209
210func createFakeUserWithPGPSibkey(tc libkb.TestContext) *FakeUser {
211	fu := CreateAndSignupFakeUser(tc, "pgp")
212
213	arg := PGPKeyImportEngineArg{
214		Gen: &libkb.PGPGenArg{
215			PrimaryBits: 768,
216			SubkeyBits:  768,
217		},
218	}
219	if err := arg.Gen.MakeAllIds(tc.G); err != nil {
220		tc.T.Fatal(err)
221	}
222	uis := libkb.UIs{
223		LogUI:    tc.G.UI.GetLogUI(),
224		SecretUI: fu.NewSecretUI(),
225	}
226	eng := NewPGPKeyImportEngine(tc.G, arg)
227	m := NewMetaContextForTest(tc).WithUIs(uis)
228	err := RunEngine2(m, eng)
229	if err != nil {
230		tc.T.Fatal(err)
231	}
232	return fu
233}
234
235func createFakeUserWithPGPSibkeyPaper(tc libkb.TestContext) *FakeUser {
236	fu := CreateAndSignupFakeUserPaper(tc, "pgp")
237
238	arg := PGPKeyImportEngineArg{
239		Gen: &libkb.PGPGenArg{
240			PrimaryBits: 768,
241			SubkeyBits:  768,
242		},
243	}
244	if err := arg.Gen.MakeAllIds(tc.G); err != nil {
245		tc.T.Fatal(err)
246	}
247	uis := libkb.UIs{
248		LogUI:    tc.G.UI.GetLogUI(),
249		SecretUI: fu.NewSecretUI(),
250	}
251	eng := NewPGPKeyImportEngine(tc.G, arg)
252	m := NewMetaContextForTest(tc).WithUIs(uis)
253	err := RunEngine2(m, eng)
254	if err != nil {
255		tc.T.Fatal(err)
256	}
257	return fu
258}
259
260func createFakeUserWithPGPSibkeyPushed(tc libkb.TestContext) *FakeUser {
261	fu := CreateAndSignupFakeUser(tc, "pgp")
262
263	arg := PGPKeyImportEngineArg{
264		Gen: &libkb.PGPGenArg{
265			PrimaryBits: 768,
266			SubkeyBits:  768,
267		},
268		PushSecret: true,
269		NoSave:     true,
270	}
271	if err := arg.Gen.MakeAllIds(tc.G); err != nil {
272		tc.T.Fatal(err)
273	}
274	uis := libkb.UIs{
275		LogUI:    tc.G.UI.GetLogUI(),
276		SecretUI: fu.NewSecretUI(),
277	}
278	eng := NewPGPKeyImportEngine(tc.G, arg)
279	m := NewMetaContextForTest(tc).WithUIs(uis)
280	err := RunEngine2(m, eng)
281	if err != nil {
282		tc.T.Fatal(err)
283	}
284	return fu
285}
286
287func createFakeUserWithPGPSibkeyPushedPaper(tc libkb.TestContext) *FakeUser {
288	fu := CreateAndSignupFakeUserPaper(tc, "pgp")
289
290	arg := PGPKeyImportEngineArg{
291		Gen: &libkb.PGPGenArg{
292			PrimaryBits: 768,
293			SubkeyBits:  768,
294		},
295		PushSecret: true,
296		NoSave:     true,
297	}
298	if err := arg.Gen.MakeAllIds(tc.G); err != nil {
299		tc.T.Fatal(err)
300	}
301	uis := libkb.UIs{
302		LogUI:    tc.G.UI.GetLogUI(),
303		SecretUI: fu.NewSecretUI(),
304	}
305	eng := NewPGPKeyImportEngine(tc.G, arg)
306	m := NewMetaContextForTest(tc).WithUIs(uis)
307	err := RunEngine2(m, eng)
308	if err != nil {
309		tc.T.Fatal(err)
310	}
311	return fu
312}
313
314func createFakeUserWithPGPSibkeyPregen(tc libkb.TestContext, pregen *libkb.PGPKeyBundle) *FakeUser {
315	fu := CreateAndSignupFakeUser(tc, "pgp")
316
317	arg := PGPKeyImportEngineArg{
318		Pregen: pregen,
319	}
320	uis := libkb.UIs{
321		LogUI:    tc.G.UI.GetLogUI(),
322		SecretUI: fu.NewSecretUI(),
323	}
324	eng := NewPGPKeyImportEngine(tc.G, arg)
325	m := NewMetaContextForTest(tc).WithUIs(uis)
326	err := RunEngine2(m, eng)
327	if err != nil {
328		tc.T.Fatal(err)
329	}
330	return fu
331}
332
333// fakeLKS is used to create a lks that has the server half when
334// creating a fake user that doesn't have a device.
335func (s *SignupEngine) fakeLKS(m libkb.MetaContext) error {
336	s.lks = libkb.NewLKSec(s.ppStream, s.uid)
337	return s.lks.GenerateServerHalf()
338}
339