github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/pgp_pull_test.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package engine
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/keybase/client/go/libkb"
    10  	"github.com/stretchr/testify/require"
    11  	"golang.org/x/net/context"
    12  )
    13  
    14  const aliceFp string = "2373fd089f28f328916b88f99c7927c0bdfdadf9"
    15  const bobFp string = "91fe9b24ef6706b1f7898f2059a2a43f8b731f29"
    16  
    17  func createUserWhoTracks(tc libkb.TestContext, trackedUsers []string, sigVersion libkb.SigVersion) *FakeUser {
    18  	fu := CreateAndSignupFakeUser(tc, "pull")
    19  	fu.LoginOrBust(tc)
    20  
    21  	for _, trackedUser := range trackedUsers {
    22  		_, _, err := runTrack(tc, fu, trackedUser, sigVersion)
    23  		require.NoError(tc.T, err, "error while tracking")
    24  	}
    25  	return fu
    26  }
    27  
    28  func untrackUserList(tc libkb.TestContext, fu *FakeUser, trackedUsers []string, sigVersion libkb.SigVersion) {
    29  	for _, trackedUser := range trackedUsers {
    30  		err := runUntrack(tc, fu, trackedUser, sigVersion)
    31  		require.NoError(tc.T, err, "error while untracking %s", trackedUser)
    32  	}
    33  }
    34  
    35  func createGpgClient(tc libkb.TestContext) *libkb.GpgCLI {
    36  	gpgClient := libkb.NewGpgCLI(tc.G, tc.G.UI.GetLogUI())
    37  	err := gpgClient.Configure(tc.MetaContext())
    38  	require.NoError(tc.T, err, "Error while configuring gpg client.")
    39  	return gpgClient
    40  }
    41  
    42  func assertKeysPresent(t *testing.T, gpgClient *libkb.GpgCLI, fingerprints []string) {
    43  	for _, fingerprint := range fingerprints {
    44  		fpObj, err := gpgClient.ImportKey(gpgClient.MetaContext(context.Background()), false /*secret*/, *libkb.PGPFingerprintFromHexNoError(fingerprint), "")
    45  		require.NoError(t, err, "Should have fingerprint in keyring: %s", fingerprint)
    46  		require.Equal(t, fingerprint, fpObj.GetFingerprint().String())
    47  	}
    48  }
    49  
    50  func assertKeysMissing(t *testing.T, gpgClient *libkb.GpgCLI, fingerprints []string) {
    51  	for _, fingerprint := range fingerprints {
    52  		_, err := gpgClient.ImportKey(gpgClient.MetaContext(context.Background()), false /*secret*/, *libkb.PGPFingerprintFromHexNoError(fingerprint), "")
    53  		require.Error(t, err, "Should not already have fingerprint in keyring: %s", fingerprint)
    54  	}
    55  }
    56  
    57  func runPGPPull(tc libkb.TestContext, arg PGPPullEngineArg) {
    58  	eng := NewPGPPullEngine(tc.G, &arg)
    59  	m := NewMetaContextForTestWithLogUI(tc)
    60  	err := RunEngine2(m, eng)
    61  	require.NoError(tc.T, err, "Error in PGPPullEngine")
    62  }
    63  
    64  func runPGPPullExpectingError(tc libkb.TestContext, arg PGPPullEngineArg) {
    65  	eng := NewPGPPullEngine(tc.G, &arg)
    66  	m := NewMetaContextForTestWithLogUI(tc)
    67  	err := RunEngine2(m, eng)
    68  	require.Error(tc.T, err, "PGPPullEngine should have failed.")
    69  }
    70  
    71  func TestPGPPullAll(t *testing.T) {
    72  	tc := SetupEngineTest(t, "pgp_pull")
    73  	defer tc.Cleanup()
    74  	sigVersion := libkb.GetDefaultSigVersion(tc.G)
    75  
    76  	users := []string{"t_alice", "t_bob"}
    77  	fu := createUserWhoTracks(tc, users, sigVersion)
    78  	defer untrackUserList(tc, fu, users, sigVersion)
    79  	gpgClient := createGpgClient(tc)
    80  
    81  	assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp})
    82  
    83  	runPGPPull(tc, PGPPullEngineArg{})
    84  
    85  	assertKeysPresent(t, gpgClient, []string{aliceFp, bobFp})
    86  }
    87  
    88  func TestPGPPullOne(t *testing.T) {
    89  	tc := SetupEngineTest(t, "pgp_pull")
    90  	defer tc.Cleanup()
    91  	sigVersion := libkb.GetDefaultSigVersion(tc.G)
    92  
    93  	users := []string{"t_alice", "t_bob"}
    94  	fu := createUserWhoTracks(tc, users, sigVersion)
    95  	defer untrackUserList(tc, fu, users, sigVersion)
    96  	gpgClient := createGpgClient(tc)
    97  
    98  	assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp})
    99  
   100  	runPGPPull(tc, PGPPullEngineArg{
   101  		// ID'ing the same user twice should be ok.
   102  		UserAsserts: []string{"t_bob"},
   103  	})
   104  
   105  	assertKeysPresent(t, gpgClient, []string{bobFp})
   106  	assertKeysMissing(t, gpgClient, []string{aliceFp})
   107  }
   108  
   109  func TestPGPPullBadIDs(t *testing.T) {
   110  	tc := SetupEngineTest(t, "pgp_pull")
   111  	defer tc.Cleanup()
   112  	sigVersion := libkb.GetDefaultSigVersion(tc.G)
   113  
   114  	users := []string{"t_alice", "t_bob"}
   115  	fu := createUserWhoTracks(tc, users, sigVersion)
   116  	defer untrackUserList(tc, fu, users, sigVersion)
   117  	gpgClient := createGpgClient(tc)
   118  
   119  	assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp})
   120  
   121  	runPGPPullExpectingError(tc, PGPPullEngineArg{
   122  		// ID'ing invalid user should fail the pull.
   123  		UserAsserts: []string{"t_bob", "t_NOT_TRACKED_BY_ME"},
   124  	})
   125  
   126  	assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp})
   127  }
   128  
   129  func TestPGPPullNotTracked(t *testing.T) {
   130  	tc := SetupEngineTest(t, "pgp_pull")
   131  	defer tc.Cleanup()
   132  	sigVersion := libkb.GetDefaultSigVersion(tc.G)
   133  
   134  	// Only tracking alice
   135  	users := []string{"t_alice"}
   136  	fu := createUserWhoTracks(tc, users, sigVersion)
   137  	defer untrackUserList(tc, fu, users, sigVersion)
   138  	gpgClient := createGpgClient(tc)
   139  
   140  	// But want to pull bot alice and bob.
   141  	assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp})
   142  
   143  	fui := &FakeIdentifyUI{FakeConfirm: true}
   144  	uis := libkb.UIs{
   145  		LogUI:      tc.G.UI.GetLogUI(),
   146  		GPGUI:      &gpgtestui{},
   147  		IdentifyUI: fui,
   148  	}
   149  	eng := NewPGPPullEngine(tc.G, &PGPPullEngineArg{
   150  		UserAsserts: []string{"t_bob", "t_alice"},
   151  	})
   152  	m := NewMetaContextForTest(tc).WithUIs(uis)
   153  	err := RunEngine2(m, eng)
   154  	require.NoError(t, err)
   155  	require.Equal(t, 1, fui.StartCount, "Expected 1 ID UI prompt")
   156  
   157  	assertKeysPresent(t, gpgClient, []string{bobFp, aliceFp})
   158  }
   159  
   160  func TestPGPPullNotLoggedIn(t *testing.T) {
   161  	tc := SetupEngineTest(t, "track")
   162  	defer tc.Cleanup()
   163  
   164  	gpgClient := createGpgClient(tc)
   165  
   166  	assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp})
   167  
   168  	fui := &FakeIdentifyUI{FakeConfirm: true}
   169  	uis := libkb.UIs{
   170  		LogUI:      tc.G.UI.GetLogUI(),
   171  		GPGUI:      &gpgtestui{},
   172  		IdentifyUI: fui,
   173  	}
   174  	eng := NewPGPPullEngine(tc.G, &PGPPullEngineArg{
   175  		UserAsserts: []string{"t_bob", "t_alice"},
   176  	})
   177  	m := NewMetaContextForTest(tc).WithUIs(uis)
   178  	err := RunEngine2(m, eng)
   179  	require.NoError(t, err)
   180  	require.Equal(t, 2, fui.StartCount, "Expected 2 ID UI prompt")
   181  
   182  	assertKeysPresent(t, gpgClient, []string{aliceFp, bobFp})
   183  }
   184  
   185  func TestPGPPullMultiplePrompts(t *testing.T) {
   186  	tc := SetupEngineTest(t, "pgp_pull")
   187  	defer tc.Cleanup()
   188  	sigVersion := libkb.GetDefaultSigVersion(tc.G)
   189  	createUserWhoTracks(tc, []string{}, sigVersion)
   190  
   191  	gpgClient := createGpgClient(tc)
   192  	assertKeysMissing(t, gpgClient, []string{aliceFp})
   193  
   194  	// Try the first time, declining in prompt. We expect keys not to
   195  	// be imported.
   196  	fui := &FakeIdentifyUI{FakeConfirm: false}
   197  	uis := libkb.UIs{
   198  		LogUI:      tc.G.UI.GetLogUI(),
   199  		GPGUI:      &gpgtestui{},
   200  		IdentifyUI: fui,
   201  	}
   202  
   203  	eng := NewPGPPullEngine(tc.G, &PGPPullEngineArg{
   204  		UserAsserts: []string{"t_alice"},
   205  	})
   206  	m := NewMetaContextForTest(tc).WithUIs(uis)
   207  	err := RunEngine2(m, eng)
   208  	require.NoError(t, err)
   209  
   210  	require.Equal(t, 1, fui.StartCount, "Expected 1 ID UI prompt")
   211  	assertKeysMissing(t, gpgClient, []string{aliceFp})
   212  
   213  	// Run again, declining like before, but make sure we got asked
   214  	// second time and our answer wasn't just cached.
   215  	err = RunEngine2(m, eng)
   216  	require.NoError(t, err)
   217  
   218  	require.Equal(t, 2, fui.StartCount, "Expected 2 ID UI prompts")
   219  	assertKeysMissing(t, gpgClient, []string{aliceFp})
   220  
   221  	// Run again, attempt to confirm in prompt. PGP Pull should ask us
   222  	// again even though we declined before, and successfully import
   223  	// the keys.
   224  	fui.FakeConfirm = true
   225  	err = RunEngine2(m, eng)
   226  	require.NoError(t, err)
   227  
   228  	require.Equal(t, 3, fui.StartCount, "Expected 2 ID UI prompts")
   229  	assertKeysPresent(t, gpgClient, []string{aliceFp})
   230  }