github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/service/prove.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 service 5 6 import ( 7 "fmt" 8 "sort" 9 10 "github.com/keybase/client/go/engine" 11 "github.com/keybase/client/go/libkb" 12 keybase1 "github.com/keybase/client/go/protocol/keybase1" 13 "github.com/keybase/go-framed-msgpack-rpc/rpc" 14 "golang.org/x/net/context" 15 ) 16 17 // ProveHandler is the service side of proving ownership of social media accounts 18 // like Twitter and Github. 19 type ProveHandler struct { 20 *BaseHandler 21 libkb.Contextified 22 } 23 24 type proveUI struct { 25 sessionID int 26 cli keybase1.ProveUiClient 27 } 28 29 // NewProveHandler makes a new ProveHandler object from an RPC transport. 30 func NewProveHandler(xp rpc.Transporter, g *libkb.GlobalContext) *ProveHandler { 31 return &ProveHandler{ 32 BaseHandler: NewBaseHandler(g, xp), 33 Contextified: libkb.NewContextified(g), 34 } 35 } 36 37 func (p *proveUI) PromptOverwrite(ctx context.Context, arg keybase1.PromptOverwriteArg) (b bool, err error) { 38 arg.SessionID = p.sessionID 39 return p.cli.PromptOverwrite(ctx, arg) 40 } 41 func (p *proveUI) PromptUsername(ctx context.Context, arg keybase1.PromptUsernameArg) (un string, err error) { 42 arg.SessionID = p.sessionID 43 return p.cli.PromptUsername(ctx, arg) 44 } 45 func (p *proveUI) OutputPrechecks(ctx context.Context, arg keybase1.OutputPrechecksArg) error { 46 arg.SessionID = p.sessionID 47 return p.cli.OutputPrechecks(ctx, arg) 48 } 49 func (p *proveUI) PreProofWarning(ctx context.Context, arg keybase1.PreProofWarningArg) (ok bool, err error) { 50 arg.SessionID = p.sessionID 51 return p.cli.PreProofWarning(ctx, arg) 52 } 53 func (p *proveUI) OutputInstructions(ctx context.Context, arg keybase1.OutputInstructionsArg) (err error) { 54 arg.SessionID = p.sessionID 55 return p.cli.OutputInstructions(ctx, arg) 56 } 57 func (p *proveUI) OkToCheck(ctx context.Context, arg keybase1.OkToCheckArg) (bool, error) { 58 arg.SessionID = p.sessionID 59 return p.cli.OkToCheck(ctx, arg) 60 } 61 func (p *proveUI) Checking(ctx context.Context, arg keybase1.CheckingArg) error { 62 arg.SessionID = p.sessionID 63 return p.cli.Checking(ctx, arg) 64 } 65 func (p *proveUI) ContinueChecking(ctx context.Context, _ int) (bool, error) { 66 return p.cli.ContinueChecking(ctx, p.sessionID) 67 } 68 func (p *proveUI) DisplayRecheckWarning(ctx context.Context, arg keybase1.DisplayRecheckWarningArg) error { 69 arg.SessionID = p.sessionID 70 return p.cli.DisplayRecheckWarning(ctx, arg) 71 } 72 73 func (ph *ProveHandler) getProveUI(sessionID int) libkb.ProveUI { 74 return &proveUI{sessionID, keybase1.ProveUiClient{Cli: ph.rpcClient()}} 75 } 76 77 // Prove handles the `keybase.1.startProof` RPC. 78 func (ph *ProveHandler) StartProof(ctx context.Context, arg keybase1.StartProofArg) (res keybase1.StartProofResult, err error) { 79 ctx = libkb.WithLogTag(ctx, "PV") 80 defer ph.G().CTrace(ctx, fmt.Sprintf("StartProof: Service: %v, Username: %v", arg.Service, arg.Username), &err)() 81 eng := engine.NewProve(ph.G(), &arg) 82 uis := libkb.UIs{ 83 ProveUI: ph.getProveUI(arg.SessionID), 84 SecretUI: ph.getSecretUI(arg.SessionID, ph.G()), 85 LogUI: ph.getLogUI(arg.SessionID), 86 SessionID: arg.SessionID, 87 } 88 m := libkb.NewMetaContext(ctx, ph.G()).WithUIs(uis) 89 if err = engine.RunEngine2(m, eng); err != nil { 90 return res, err 91 } 92 res.SigID = eng.SigID() 93 return res, err 94 } 95 96 func (ph *ProveHandler) ValidateUsername(ctx context.Context, arg keybase1.ValidateUsernameArg) error { 97 mctx := libkb.NewMetaContext(ctx, ph.G()) 98 serviceType := mctx.G().GetProofServices().GetServiceType(ctx, arg.Service) 99 if serviceType == nil { 100 return libkb.BadServiceError{Service: arg.Service} 101 } 102 _, err := serviceType.NormalizeRemoteName(mctx, arg.Remotename) 103 return err 104 } 105 106 // Prove handles the `keybase.1.checkProof` RPC. 107 func (ph *ProveHandler) CheckProof(ctx context.Context, arg keybase1.CheckProofArg) (res keybase1.CheckProofStatus, err error) { 108 ctx = libkb.WithLogTag(ctx, "PV") 109 defer ph.G().CTrace(ctx, fmt.Sprintf("CheckProof: SigID: %v", arg.SigID), &err)() 110 eng := engine.NewProveCheck(ph.G(), arg.SigID) 111 m := libkb.NewMetaContext(ctx, ph.G()) 112 if err = engine.RunEngine2(m, eng); err != nil { 113 return res, err 114 } 115 found, status, state, text := eng.Results() 116 return keybase1.CheckProofStatus{ 117 Found: found, 118 Status: status, 119 State: state, 120 ProofText: text, 121 }, nil 122 } 123 124 var choiceProofServices = map[string]int{ 125 "twitter": 1, 126 "github": 2, 127 "reddit": 3, 128 "hackernews": 4, 129 "facebook": 5, 130 "web": 6, 131 "https": 7, 132 "http": 8, 133 "dns": 9, 134 "rooter": 10, 135 "mastodon.social": 11, 136 } 137 138 func (ph *ProveHandler) ListSomeProofServices(ctx context.Context) (res []string, err error) { 139 ctx = libkb.WithLogTag(ctx, "PV") 140 defer ph.G().CTrace(ctx, "ListSomeProofServices", &err)() 141 mctx := libkb.NewMetaContext(ctx, ph.G()) 142 var services []string 143 for _, service := range ph.G().GetProofServices().ListServicesThatAcceptNewProofs(mctx) { 144 if _, found := choiceProofServices[service]; found { 145 services = append(services, service) 146 } 147 } 148 sort.SliceStable(services, func(i, j int) bool { return choiceProofServices[services[i]] < choiceProofServices[services[j]] }) 149 return services, nil 150 } 151 152 func (ph *ProveHandler) ListProofServices(ctx context.Context) (res []string, err error) { 153 ctx = libkb.WithLogTag(ctx, "PV") 154 defer ph.G().CTrace(ctx, "ListProofServices", &err)() 155 mctx := libkb.NewMetaContext(ctx, ph.G()) 156 return ph.G().GetProofServices().ListServicesThatAcceptNewProofs(mctx), nil 157 }