github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/tlfhandle/identify_util_test.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package tlfhandle 6 7 import ( 8 "fmt" 9 "sync" 10 "testing" 11 12 "github.com/keybase/client/go/externals" 13 "github.com/keybase/client/go/kbfs/idutil" 14 idutiltest "github.com/keybase/client/go/kbfs/idutil/test" 15 "github.com/keybase/client/go/kbfs/tlf" 16 kbname "github.com/keybase/client/go/kbun" 17 "github.com/keybase/client/go/libkb" 18 "github.com/keybase/client/go/protocol/keybase1" 19 "github.com/stretchr/testify/require" 20 "golang.org/x/net/context" 21 ) 22 23 type testIdentifier struct { 24 assertions map[string]idutil.UserInfo 25 assertionsBrokenTracks map[string]idutil.UserInfo 26 implicitTeams map[string]idutil.ImplicitTeamInfo 27 identifiedIDsLock sync.Mutex 28 identifiedIDs map[keybase1.UserOrTeamID]bool 29 } 30 31 func (ti *testIdentifier) Identify( 32 ctx context.Context, assertion, reason string, 33 _ keybase1.OfflineAvailability) ( 34 kbname.NormalizedUsername, keybase1.UserOrTeamID, error) { 35 ei := GetExtendedIdentify(ctx) 36 userInfo, ok := ti.assertionsBrokenTracks[assertion] 37 if ok { 38 if !ei.Behavior.WarningInsteadOfErrorOnBrokenTracks() { 39 return kbname.NormalizedUsername(""), keybase1.UserOrTeamID(""), 40 libkb.UnmetAssertionError{ 41 User: "imtotalllymakingthisup", 42 Remote: true, 43 } 44 } 45 ei.UserBreak( 46 ctx, userInfo.Name, userInfo.UID, &keybase1.IdentifyTrackBreaks{}) 47 return userInfo.Name, userInfo.UID.AsUserOrTeam(), nil 48 } 49 50 userInfo, ok = ti.assertions[assertion] 51 if !ok { 52 return kbname.NormalizedUsername(""), keybase1.UserOrTeamID(""), 53 idutil.NoSuchUserError{Input: assertion} 54 } 55 56 func() { 57 ti.identifiedIDsLock.Lock() 58 defer ti.identifiedIDsLock.Unlock() 59 if ti.identifiedIDs == nil { 60 ti.identifiedIDs = make(map[keybase1.UserOrTeamID]bool) 61 } 62 ti.identifiedIDs[userInfo.UID.AsUserOrTeam()] = true 63 }() 64 65 ei.UserBreak(ctx, userInfo.Name, userInfo.UID, nil) 66 return userInfo.Name, userInfo.UID.AsUserOrTeam(), nil 67 } 68 69 func (ti *testIdentifier) NormalizeSocialAssertion( 70 ctx context.Context, assertion string) (keybase1.SocialAssertion, error) { 71 socialAssertion, isSocialAssertion := externals.NormalizeSocialAssertionStatic(ctx, assertion) 72 if !isSocialAssertion { 73 return keybase1.SocialAssertion{}, fmt.Errorf("Invalid social assertion") 74 } 75 return socialAssertion, nil 76 } 77 78 func (ti *testIdentifier) IdentifyImplicitTeam( 79 _ context.Context, assertions, suffix string, ty tlf.Type, _ string, 80 _ keybase1.OfflineAvailability) (idutil.ImplicitTeamInfo, error) { 81 // TODO: canonicalize name. 82 name := assertions 83 if suffix != "" { 84 name += " " + suffix 85 } 86 87 iteamInfo, ok := ti.implicitTeams[ty.String()+":"+name] 88 if !ok { 89 return idutil.ImplicitTeamInfo{}, idutil.NoSuchTeamError{Input: name} 90 } 91 92 func() { 93 ti.identifiedIDsLock.Lock() 94 defer ti.identifiedIDsLock.Unlock() 95 if ti.identifiedIDs == nil { 96 ti.identifiedIDs = make(map[keybase1.UserOrTeamID]bool) 97 } 98 ti.identifiedIDs[iteamInfo.TID.AsUserOrTeam()] = true 99 }() 100 101 return iteamInfo, nil 102 } 103 104 func makeNugAndTIForTest() ( 105 idutiltest.NormalizedUsernameGetter, *testIdentifier) { 106 return idutiltest.NormalizedUsernameGetter{ 107 keybase1.MakeTestUID(1).AsUserOrTeam(): "alice", 108 keybase1.MakeTestUID(2).AsUserOrTeam(): "bob", 109 keybase1.MakeTestUID(3).AsUserOrTeam(): "charlie", 110 }, &testIdentifier{ 111 assertions: map[string]idutil.UserInfo{ 112 "alice": { 113 Name: "alice", 114 UID: keybase1.MakeTestUID(1), 115 }, 116 "bob": { 117 Name: "bob", 118 UID: keybase1.MakeTestUID(2), 119 }, 120 "charlie": { 121 Name: "charlie", 122 UID: keybase1.MakeTestUID(3), 123 }, 124 }, 125 } 126 } 127 128 func TestIdentify(t *testing.T) { 129 nug, ti := makeNugAndTIForTest() 130 131 ids := make(map[keybase1.UserOrTeamID]bool, len(nug)) 132 for u := range nug { 133 ids[u] = true 134 } 135 136 err := identifyUsersForTLF( 137 context.Background(), nug, ti, nug.UIDMap(), tlf.Private, 138 keybase1.OfflineAvailability_NONE) 139 require.NoError(t, err) 140 require.Equal(t, ids, ti.identifiedIDs) 141 } 142 143 func TestIdentifyAlternativeBehaviors(t *testing.T) { 144 nug, ti := makeNugAndTIForTest() 145 nug[keybase1.MakeTestUID(1001).AsUserOrTeam()] = "zebra" 146 ti.assertionsBrokenTracks = map[string]idutil.UserInfo{ 147 "zebra": { 148 Name: "zebra", 149 UID: keybase1.MakeTestUID(1001), 150 }, 151 } 152 153 ctx, err := MakeExtendedIdentify(context.Background(), 154 keybase1.TLFIdentifyBehavior_CHAT_CLI) 155 require.NoError(t, err) 156 err = identifyUsersForTLF( 157 ctx, nug, ti, nug.UIDMap(), tlf.Private, 158 keybase1.OfflineAvailability_NONE) 159 require.Error(t, err) 160 161 ctx, err = MakeExtendedIdentify(context.Background(), 162 keybase1.TLFIdentifyBehavior_CHAT_GUI) 163 require.NoError(t, err) 164 err = identifyUsersForTLF( 165 ctx, nug, ti, nug.UIDMap(), tlf.Private, 166 keybase1.OfflineAvailability_NONE) 167 require.NoError(t, err) 168 tb := GetExtendedIdentify(ctx).GetTlfBreakAndClose() 169 require.Len(t, tb.Breaks, 1) 170 require.Equal(t, "zebra", tb.Breaks[0].User.Username) 171 require.NotNil(t, tb.Breaks[0].Breaks) 172 } 173 174 func TestIdentifyImplicitTeams(t *testing.T) { 175 nug, ti := makeNugAndTIForTest() 176 177 // Add implicit teams. 178 pubID := keybase1.MakeTestTeamID(1, true) 179 privID := keybase1.MakeTestTeamID(1, false) 180 suffixID := keybase1.MakeTestTeamID(2, false) 181 ti.implicitTeams = map[string]idutil.ImplicitTeamInfo{ 182 "public:alice,bob": { 183 Name: "alice,bob", 184 TID: pubID, 185 }, 186 "private:alice,bob": { 187 Name: "alice,bob", 188 TID: privID, 189 }, 190 "private:alice,bob (conflicted copy 2016-03-14 #3)": { 191 Name: "alice,bob (conflicted copy 2016-03-14 #3)", 192 TID: suffixID, 193 }, 194 } 195 196 ids := make(map[keybase1.UserOrTeamID]bool, len(ti.implicitTeams)) 197 for _, iteamInfo := range ti.implicitTeams { 198 ids[iteamInfo.TID.AsUserOrTeam()] = true 199 } 200 201 err := identifyUsersForTLF( 202 context.Background(), nug, ti, 203 map[keybase1.UserOrTeamID]kbname.NormalizedUsername{ 204 privID.AsUserOrTeam(): "alice,bob", 205 }, tlf.Private, keybase1.OfflineAvailability_NONE) 206 require.NoError(t, err) 207 err = identifyUsersForTLF( 208 context.Background(), nug, ti, 209 map[keybase1.UserOrTeamID]kbname.NormalizedUsername{ 210 pubID.AsUserOrTeam(): "alice,bob", 211 }, tlf.Public, keybase1.OfflineAvailability_NONE) 212 require.NoError(t, err) 213 err = identifyUsersForTLF( 214 context.Background(), nug, ti, 215 map[keybase1.UserOrTeamID]kbname.NormalizedUsername{ 216 suffixID.AsUserOrTeam(): "alice,bob (conflicted copy 2016-03-14 #3)", 217 }, tlf.Private, keybase1.OfflineAvailability_NONE) 218 require.NoError(t, err) 219 require.Equal(t, ids, ti.identifiedIDs) 220 }