1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package systests
5
6import (
7	"testing"
8
9	"github.com/keybase/client/go/client"
10	"github.com/keybase/client/go/libkb"
11	"github.com/keybase/client/go/service"
12	"golang.org/x/net/context"
13
14	keybase1 "github.com/keybase/client/go/protocol/keybase1"
15	"github.com/keybase/go-framed-msgpack-rpc/rpc"
16)
17
18func TestSecretUI(t *testing.T) {
19	tc := setupTest(t, "secret_ui")
20	defer tc.Cleanup()
21	tc1 := cloneContext(tc)
22	defer tc1.Cleanup()
23	tc2 := cloneContext(tc)
24	defer tc2.Cleanup()
25
26	stopCh := make(chan error)
27	svc := service.NewService(tc.G, false)
28	startCh := svc.GetStartChannel()
29	go func() {
30		err := svc.Run()
31		if err != nil {
32			t.Logf("Running the service produced an error: %v", err)
33		}
34		stopCh <- err
35	}()
36
37	// Wait for the server to start up
38	<-startCh
39
40	var err error
41	check := func() {
42		if err != nil {
43			t.Fatal(err)
44		}
45	}
46
47	sui := newSecretUI()
48	cli, xp, err := client.GetRPCClientWithContext(tc2.G)
49	check()
50	srv := rpc.NewServer(xp, nil)
51	err = srv.Register(keybase1.SecretUiProtocol(sui))
52	check()
53	ncli := keybase1.DelegateUiCtlClient{Cli: cli}
54	err = ncli.RegisterSecretUI(context.TODO())
55	check()
56
57	// run login command
58	loginCmdUI := &loginCmdUI{
59		Contextified: libkb.NewContextified(tc2.G),
60	}
61	tc2.G.SetUI(loginCmdUI)
62	cmd := client.NewCmdLoginRunner(tc2.G)
63	cmd.SessionID = 19
64	err = cmd.Run()
65	if err == nil {
66		t.Fatal("login worked, when it should have failed")
67	}
68
69	// check that delegate ui was called:
70	if !sui.getPassphrase {
71		t.Logf("secret ui: %+v", sui)
72		t.Error("delegate secret UI GetPassphrase was not called during login cmd")
73	}
74
75	// check that delegate ui session id was correct:
76	if sui.getPassphraseSessionID != cmd.SessionID {
77		t.Errorf("delegate secret UI session ID: %d, expected %d", sui.getPassphraseSessionID, cmd.SessionID)
78	}
79
80	if err := CtlStop(tc1.G); err != nil {
81		t.Errorf("Error in stopping service: %v", err)
82	}
83
84	// If the server failed, it's also an error
85	err = <-stopCh
86	check()
87}
88
89type secretUI struct {
90	getPassphrase          bool
91	getPassphraseSessionID int
92}
93
94// secretUI implements the keybase1.IdentifyUiInterface
95var _ keybase1.SecretUiInterface = (*secretUI)(nil)
96
97func newSecretUI() *secretUI {
98	return &secretUI{}
99}
100
101func (s *secretUI) GetPassphrase(_ context.Context, arg keybase1.GetPassphraseArg) (res keybase1.GetPassphraseRes, err error) {
102	s.getPassphrase = true
103	s.getPassphraseSessionID = arg.SessionID
104	res.Passphrase = "XXXXXXXXXXXX"
105	return res, nil
106}
107
108type loginCmdUI struct {
109	baseNullUI
110	libkb.Contextified
111}
112
113func (u *loginCmdUI) GetLoginUI() libkb.LoginUI {
114	return &loginUI{Contextified: libkb.NewContextified(u.G())}
115}
116
117func (u *loginCmdUI) GetProvisionUI(libkb.KexRole) libkb.ProvisionUI {
118	return &provisionUI{Contextified: libkb.NewContextified(u.G())}
119}
120
121type loginUI struct {
122	libkb.Contextified
123}
124
125var _ libkb.LoginUI = (*loginUI)(nil)
126
127func (u *loginUI) DisplayPaperKeyPhrase(context.Context, keybase1.DisplayPaperKeyPhraseArg) error {
128	return nil
129}
130func (u *loginUI) DisplayPrimaryPaperKey(context.Context, keybase1.DisplayPrimaryPaperKeyArg) error {
131	return nil
132}
133func (u *loginUI) PromptRevokePaperKeys(context.Context, keybase1.PromptRevokePaperKeysArg) (bool, error) {
134	return false, nil
135}
136func (u *loginUI) GetEmailOrUsername(context.Context, int) (string, error) {
137	return "t_alice", nil
138}
139func (u *loginUI) PromptResetAccount(_ context.Context, arg keybase1.PromptResetAccountArg) (keybase1.ResetPromptResponse, error) {
140	return keybase1.ResetPromptResponse_NOTHING, nil
141}
142func (u *loginUI) DisplayResetProgress(_ context.Context, arg keybase1.DisplayResetProgressArg) error {
143	return nil
144}
145func (u *loginUI) ExplainDeviceRecovery(_ context.Context, arg keybase1.ExplainDeviceRecoveryArg) error {
146	return nil
147}
148func (u *loginUI) PromptPassphraseRecovery(_ context.Context, arg keybase1.PromptPassphraseRecoveryArg) (bool, error) {
149	return false, nil
150}
151func (u *loginUI) ChooseDeviceToRecoverWith(_ context.Context, arg keybase1.ChooseDeviceToRecoverWithArg) (keybase1.DeviceID, error) {
152	return "", nil
153}
154func (u *loginUI) DisplayResetMessage(_ context.Context, arg keybase1.DisplayResetMessageArg) error {
155	return nil
156}
157
158type provisionUI struct {
159	libkb.Contextified
160}
161
162func (u *provisionUI) ChooseProvisioningMethod(context.Context, keybase1.ChooseProvisioningMethodArg) (keybase1.ProvisionMethod, error) {
163	panic("deprecated")
164}
165func (u *provisionUI) ChooseGPGMethod(context.Context, keybase1.ChooseGPGMethodArg) (keybase1.GPGMethod, error) {
166	return keybase1.GPGMethod_GPG_IMPORT, nil
167}
168func (u *provisionUI) SwitchToGPGSignOK(context.Context, keybase1.SwitchToGPGSignOKArg) (bool, error) {
169	return true, nil
170}
171func (u *provisionUI) ChooseDevice(context.Context, keybase1.ChooseDeviceArg) (r keybase1.DeviceID, e error) {
172	return
173}
174func (u *provisionUI) ChooseDeviceType(context.Context, keybase1.ChooseDeviceTypeArg) (r keybase1.DeviceType, e error) {
175	return
176}
177func (u *provisionUI) DisplayAndPromptSecret(context.Context, keybase1.DisplayAndPromptSecretArg) (r keybase1.SecretResponse, e error) {
178	return
179}
180func (u *provisionUI) DisplaySecretExchanged(context.Context, int) error {
181	return nil
182}
183func (u *provisionUI) PromptNewDeviceName(context.Context, keybase1.PromptNewDeviceNameArg) (string, error) {
184	return "", nil
185}
186func (u *provisionUI) ProvisioneeSuccess(context.Context, keybase1.ProvisioneeSuccessArg) error {
187	return nil
188}
189func (u *provisionUI) ProvisionerSuccess(context.Context, keybase1.ProvisionerSuccessArg) error {
190	return nil
191}
192