/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/engine/engine.go
199 строк
5 KB
chrisnojima-zoom
Version 670 - clean2 (#29122)
08 июн 2026, 19:31
Не верифицирован
08 июн 2026, 19:31
1943197
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package engine import ( "fmt" "runtime/debug" "slices" "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" ) type ( Prereqs = libkb.EnginePrereqs Engine2 = libkb.Engine2 ) type UIDelegateWanter interface { WantDelegate(libkb.UIKind) bool } func requiresUI(c libkb.UIConsumer, kind libkb.UIKind) bool { if slices.Contains(c.RequiredUIs(), kind) { return true } for _, sub := range c.SubConsumers() { if requiresUI(sub, kind) { return true } } return false } // isLoggedInWithUIDAndError conveys if the user is in a logged-in state or not. // If this function returns `true`, it's because the user is logged in, // is on a provisioned device, and has an unlocked device key, If this // function returns `false`, it's because either no one has ever logged onto // this device, or someone has, and then clicked `logout`. If the return // value is `false`, and `err` is `nil`, then the service is in one of // those expected "logged out" states. If the return value is `false` // and `err` is non-`nil`, then something went wrong, and the app is in some // sort of unexpected state. If `ret` is `true`, then `uid` will convey // which user is logged in. // // Under the hood, IsLoggedIn is going through the BootstrapActiveDevice // flow and therefore will try its best to unlocked locked keys if it can // without user interaction. // // If the user is intentionally not logged into any user, don't try to // bootstrap from the secret store and just check if there is an active device. func isLoggedInWithUIDAndError(m libkb.MetaContext) (ret bool, uid keybase1.UID, err error) { if m.G().Env.GetStayLoggedOut() { return m.ActiveDevice().Valid(), m.G().Env.GetUID(), nil } ret, uid, err = libkb.BootstrapActiveDeviceWithMetaContext(m) return ret, uid, err } func isLoggedIn(m libkb.MetaContext) (ret bool, uid keybase1.UID) { if m.G().Env.GetStayLoggedOut() { return m.ActiveDevice().Valid(), m.G().Env.GetUID() } ret, uid, _ = libkb.BootstrapActiveDeviceWithMetaContext(m) return ret, uid } func isLoggedInAs(m libkb.MetaContext, uid keybase1.UID) (ret bool) { if m.G().Env.GetStayLoggedOut() { return m.ActiveDevice().Valid() && uid == m.G().Env.GetUID() } ret, err := libkb.BootstrapActiveDeviceWithMetaContextAndAssertUID(m, uid) if err != nil { m.Debug("isLoggedAs error: %s", err) } return ret } func isLoggedInWithError(m libkb.MetaContext) (ret bool, err error) { ret, _, err = isLoggedInWithUIDAndError(m) return ret, err } func runPrereqs(m libkb.MetaContext, e Engine2) error { prq := e.Prereqs() if prq.TemporarySession { if !m.HasAnySession() { return libkb.NewLoginRequiredError("need either a temporary session or a device") } } if prq.Device { ok, err := isLoggedInWithError(m) if err != nil { return err } if !ok { return libkb.DeviceRequiredError{} } } return nil } func RunEngine2(m libkb.MetaContext, e Engine2) (err error) { m = m.WithLogTag("ENG") defer m.Trace(fmt.Sprintf("RunEngine(%s)", e.Name()), &err)() if m, err = delegateUIs(m, e); err != nil { return err } if err = check(m, e); err != nil { return err } if err = runPrereqs(m, e); err != nil { return err } err = e.Run(m) return err } func getIdentifyUI3or1(m libkb.MetaContext) (libkb.IdentifyUI, error) { uir := m.G().UIRouter ret, err := uir.GetIdentify3UIAdapter(m) if ret != nil && err == nil { return ret, err } return uir.GetIdentifyUI() } func delegateUIs(m libkb.MetaContext, e Engine2) (libkb.MetaContext, error) { if m.G().UIRouter == nil { return m, nil } // currently, only doing this for SecretUI, but in future, // perhaps should iterate over all registered UIs in UIRouter. if requiresUI(e, libkb.SecretUIKind) { sessionID := m.UIs().SessionID if ui, err := m.G().UIRouter.GetSecretUI(sessionID); err != nil { return m, err } else if ui != nil { m.Debug("using delegated secret UI for engine %q (session id = %d)", e.Name(), sessionID) m = m.WithSecretUI(ui) } } if wantsDelegateUI(e, libkb.IdentifyUIKind) { m.Debug("IdentifyUI wanted for engine %q", e.Name()) ui, err := getIdentifyUI3or1(m) if err != nil { return m, err } if ui != nil { m.Debug("using delegated identify UI for engine %q", e.Name()) m = m.WithDelegatedIdentifyUI(ui) } } return m, nil } func wantsDelegateUI(e Engine2, kind libkb.UIKind) bool { if !requiresUI(e, kind) { return false } if i, ok := e.(UIDelegateWanter); ok { return i.WantDelegate(kind) } return false } func check(m libkb.MetaContext, c libkb.UIConsumer) error { if err := checkUI(m, c); err != nil { return err } for _, sub := range c.SubConsumers() { if err := check(m, sub); err != nil { if _, ok := err.(CheckError); ok { return err } return CheckError{fmt.Sprintf("%s: %s", sub.Name(), err)} } } return nil } func checkUI(m libkb.MetaContext, c libkb.UIConsumer) error { for _, ui := range c.RequiredUIs() { if !m.UIs().HasUI(ui) { return CheckError{fmt.Sprintf("%s: requires ui %q\n\n%s", c.Name(), ui, string(debug.Stack()))} } } return nil }