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  }