/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/engine/resolve_identify2.go
212 строк
6 KB
zoom-ua
gofumpt (#28710)
17 дек 2025, 17:16
Не верифицирован
17 дек 2025, 17:16
cda510b
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package engine import ( "errors" "fmt" gregor "github.com/keybase/client/go/gregor" "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" ) type ResolveThenIdentify2 struct { libkb.Contextified arg *keybase1.Identify2Arg i2eng *Identify2WithUID testArgs *Identify2WithUIDTestArgs responsibleGregorItem gregor.Item queriedName libkb.NormalizedUsername // When tracking is being performed, the identify engine is used with a tracking ui. // These options are sent to the ui based on command line options. // For normal identify, safe to leave these in their default zero state. trackOptions keybase1.TrackOptions } var _ (Engine2) = (*ResolveThenIdentify2)(nil) func NewResolveThenIdentify2(g *libkb.GlobalContext, arg *keybase1.Identify2Arg) *ResolveThenIdentify2 { return &ResolveThenIdentify2{ Contextified: libkb.NewContextified(g), arg: arg, } } func NewResolveThenIdentify2WithTrack(g *libkb.GlobalContext, arg *keybase1.Identify2Arg, topts keybase1.TrackOptions) *ResolveThenIdentify2 { return &ResolveThenIdentify2{ Contextified: libkb.NewContextified(g), arg: arg, trackOptions: topts, } } // Name is the unique engine name. func (e *ResolveThenIdentify2) Name() string { return "ResolveThenIdentify2" } // GetPrereqs returns the engine prereqs. func (e *ResolveThenIdentify2) Prereqs() Prereqs { return Prereqs{} } // RequiredUIs returns the required UIs. func (e *ResolveThenIdentify2) RequiredUIs() []libkb.UIKind { return []libkb.UIKind{} } // SubConsumers returns the other UI consumers for this engine. func (e *ResolveThenIdentify2) SubConsumers() []libkb.UIConsumer { return []libkb.UIConsumer{ &Identify2WithUID{ arg: e.arg, }, } } func (e *ResolveThenIdentify2) resolveUID(m libkb.MetaContext) (err error) { if !e.arg.Uid.IsNil() { return nil } // if no uid and no assertion, then if logged in use self uid: if len(e.arg.UserAssertion) == 0 && e.arg.AllowEmptySelfID { ok, uid := isLoggedIn(m) if ok { e.arg.Uid = uid return nil } return libkb.LoginRequiredError{Context: "to identify without specifying a user assertion"} } rres := m.G().Resolver.ResolveFullExpressionWithBody(m, e.arg.UserAssertion) if err = rres.GetError(); err != nil { m.Debug("ResolveThenIdentify2#resolveUID: failing assertion for arg %+v", e.arg) return err } e.arg.Uid = rres.GetUID() if rres.WasKBAssertion() && !e.arg.NeedProofSet { m.Debug("Assertion was 'KB' and we don't need proofset: %s", e.arg.UserAssertion) // the resolve assertion was a keybase username or UID, so remove it // from identify2 arg to allow cache hits on UID. e.arg.UserAssertion = "" // But still check on that way out that the username matches the UID e.queriedName = rres.GetNormalizedQueriedUsername() } // An optimization --- plumb through the resolve body for when we load the // user. This will save a round trip to the server. e.i2eng.ResolveBody = rres.GetBody() return nil } func (e *ResolveThenIdentify2) nameResolutionPostAssertion(m libkb.MetaContext) (err error) { // Check the server for cheating on a Name->UID resolution. After we do a userload (by UID), // we should have a merkle-verified idea of what the corresponding name is, so we check it // as a post-assertion here. if e.queriedName.IsNil() { return nil } res, err := e.Result(m) if err != nil { return err } if !libkb.NewNormalizedUsername(res.Upk.GetName()).Eq(e.queriedName) { return libkb.NewUIDMismatchError("bad user returned for " + e.queriedName.String()) } return nil } func (e *ResolveThenIdentify2) Run(m libkb.MetaContext) (err error) { m = m.WithLogTag("ID2") defer m.Trace("ResolveThenIdentify2#Run", &err)() e.i2eng = NewIdentify2WithUID(m.G(), e.arg) if e.responsibleGregorItem != nil { e.i2eng.SetResponsibleGregorItem(e.responsibleGregorItem) } e.i2eng.trackOptions = e.trackOptions if err = e.resolveUID(m); err != nil { return err } // For testing e.i2eng.testArgs = e.testArgs if err = RunEngine2(m, e.i2eng); err != nil { return err } if err = e.nameResolutionPostAssertion(m); err != nil { return err } return nil } func (e *ResolveThenIdentify2) Result(m libkb.MetaContext) (*keybase1.Identify2ResUPK2, error) { if e.i2eng == nil { return nil, errors.New("ResolveThenIdentify2#Result: no result available if the engine did not run") } return e.i2eng.Result(m) } func (e *ResolveThenIdentify2) SetResponsibleGregorItem(item gregor.Item) { e.responsibleGregorItem = item } func (e *ResolveThenIdentify2) TrackToken() keybase1.TrackToken { return e.i2eng.TrackToken() } func (e *ResolveThenIdentify2) ConfirmResult() keybase1.ConfirmResult { return e.i2eng.ConfirmResult() } func (e *ResolveThenIdentify2) GetProofSet() *libkb.ProofSet { if e.i2eng == nil { return nil } return e.i2eng.GetProofSet() } func (e *ResolveThenIdentify2) GetIdentifyOutcome() *libkb.IdentifyOutcome { if e.i2eng == nil { return nil } return e.i2eng.GetIdentifyOutcome() } // ResolveAndCheck takes as input a name (joe), social assertion (joe@twitter) // or compound assertion (joe+joe@twitter+3883883773222@pgp) and resolves // it to a user, verifying the result. Pass into it a MetaContext without any UIs set, // since it is meant to run without any UI interaction. Tracking statements // are optionally taken into account (see flag). No ID2-specific caching will be used, // but the UPAK cache will be used, and busted with ForceRepoll semantics. The output, on success, // is a populated UserPlusKeysV2. func ResolveAndCheck(m libkb.MetaContext, s string, useTracking bool) (ret keybase1.UserPlusKeysV2, err error) { m = m.WithLogTag("RAC") defer m.Trace(fmt.Sprintf("ResolveAndCheck(%q,%t)", s, useTracking), &err)() arg := keybase1.Identify2Arg{ UserAssertion: s, CanSuppressUI: true, ActLoggedOut: !useTracking, NoErrorOnTrackFailure: !useTracking, IdentifyBehavior: keybase1.TLFIdentifyBehavior_RESOLVE_AND_CHECK, } eng := NewResolveThenIdentify2(m.G(), &arg) if err = RunEngine2(m, eng); err != nil { return ret, err } res, err := eng.Result(m) if err != nil { return ret, err } // Success path. return res.Upk.Current, nil }