github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/client/cmd_sigs_list.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 client
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"golang.org/x/net/context"
    11  
    12  	"github.com/keybase/cli"
    13  	"github.com/keybase/client/go/libcmdline"
    14  	"github.com/keybase/client/go/libkb"
    15  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    16  )
    17  
    18  type CmdSigsList struct {
    19  	libkb.Contextified
    20  
    21  	filter  string
    22  	revoked bool
    23  	json    bool
    24  	verbose bool
    25  	allKeys bool
    26  	headers bool
    27  	types   map[string]bool
    28  
    29  	username string
    30  }
    31  
    32  func (s *CmdSigsList) ParseTypes(ctx *cli.Context) error {
    33  	tmp := ctx.String("type")
    34  	if len(tmp) == 0 {
    35  		return nil
    36  	}
    37  
    38  	types := map[string]bool{
    39  		"follow":         true,
    40  		"proof":          true,
    41  		"cryptocurrency": true,
    42  		"self":           true,
    43  	}
    44  
    45  	ret := make(map[string]bool)
    46  	v := strings.Split(tmp, ",")
    47  	for _, i := range v {
    48  		ok, found := types[i]
    49  		if !ok || !found {
    50  			return fmt.Errorf("Unknown signature type: %s", i)
    51  		}
    52  		ret[i] = true
    53  	}
    54  	s.types = ret
    55  	return nil
    56  }
    57  
    58  func (s *CmdSigsList) ParseArgv(ctx *cli.Context) error {
    59  	nargs := len(ctx.Args())
    60  	var err error
    61  
    62  	s.revoked = ctx.Bool("revoked")
    63  	s.json = ctx.Bool("json")
    64  	s.verbose = ctx.Bool("verbose")
    65  	s.allKeys = ctx.Bool("all-keys")
    66  	s.headers = ctx.Bool("headers")
    67  	s.filter = ctx.String("filter")
    68  
    69  	if err = s.ParseTypes(ctx); err != nil {
    70  		return err
    71  	}
    72  
    73  	if nargs == 1 {
    74  		s.username = ctx.Args()[0]
    75  	} else if nargs > 1 {
    76  		err = fmt.Errorf("List takes at most 1 arg, a username.")
    77  	}
    78  
    79  	return err
    80  }
    81  
    82  func (s *CmdSigsList) DisplayKTable(sigs []keybase1.Sig) (err error) {
    83  	if sigs == nil {
    84  		return nil
    85  	}
    86  
    87  	var cols []string
    88  
    89  	if s.headers {
    90  		cols = []string{
    91  			"#",
    92  			"SigId",
    93  			"Type",
    94  			"Date",
    95  		}
    96  		if s.revoked {
    97  			cols = append(cols, "Revoked")
    98  		}
    99  		if s.allKeys {
   100  			cols = append(cols, "Active", "Key")
   101  		}
   102  		cols = append(cols, "Body")
   103  	}
   104  
   105  	i := 0
   106  
   107  	rowfunc := func() []string {
   108  		var row []string
   109  		for ; i < len(sigs) && row == nil; i++ {
   110  			link := sigs[i]
   111  			row = []string{
   112  				fmt.Sprintf("%d", link.Seqno),
   113  				link.SigIDDisplay,
   114  				link.Type,
   115  				keybase1.FormatTime(link.CTime),
   116  			}
   117  			if s.revoked {
   118  				var ch string
   119  				if link.Revoked {
   120  					ch = "R"
   121  				} else {
   122  					ch = "."
   123  				}
   124  				row = append(row, ch)
   125  			}
   126  			if s.allKeys {
   127  				var ch string
   128  				if link.Active {
   129  					ch = "+"
   130  				} else {
   131  					ch = "-"
   132  				}
   133  				row = append(row, ch, link.Key)
   134  			}
   135  			row = append(row, link.Body)
   136  		}
   137  		return row
   138  	}
   139  
   140  	libkb.Tablify(s.G().UI.GetTerminalUI().OutputWriter(), cols, rowfunc)
   141  
   142  	return
   143  }
   144  
   145  func (s *CmdSigsList) Run() error {
   146  	cli, err := GetSigsClient(s.G())
   147  	if err != nil {
   148  		return err
   149  	}
   150  	var t *keybase1.SigTypes
   151  	if s.types != nil {
   152  		t = &keybase1.SigTypes{
   153  			Track:          s.types["follow"],
   154  			Proof:          s.types["proof"],
   155  			Cryptocurrency: s.types["cryptocurrency"],
   156  			IsSelf:         s.types["self"],
   157  		}
   158  	}
   159  	args := keybase1.SigListArgs{
   160  		Username: s.username,
   161  		AllKeys:  s.allKeys,
   162  		Filterx:  s.filter,
   163  		Verbose:  s.verbose,
   164  		Revoked:  s.revoked,
   165  		Types:    t,
   166  	}
   167  
   168  	if s.json {
   169  		json, err := cli.SigListJSON(context.TODO(), keybase1.SigListJSONArg{Arg: args})
   170  		if err != nil {
   171  			return err
   172  		}
   173  		_ = s.G().UI.GetTerminalUI().Output(json)
   174  		return nil
   175  	}
   176  
   177  	sigs, err := cli.SigList(context.TODO(), keybase1.SigListArg{Arg: args})
   178  	if err != nil {
   179  		return err
   180  	}
   181  	return s.DisplayKTable(sigs)
   182  }
   183  
   184  func NewCmdSigsList(cl *libcmdline.CommandLine, g *libkb.GlobalContext) cli.Command {
   185  	return cli.Command{
   186  		Name:         "list",
   187  		Usage:        "List signatures",
   188  		ArgumentHelp: "[username]",
   189  		Action: func(c *cli.Context) {
   190  			cl.ChooseCommand(&CmdSigsList{Contextified: libkb.NewContextified(g)}, "list", c)
   191  		},
   192  		Flags: []cli.Flag{
   193  			cli.BoolFlag{
   194  				Name:  "r, revoked",
   195  				Usage: "Include revoked signatures.",
   196  			},
   197  			cli.BoolFlag{
   198  				Name:  "j, json",
   199  				Usage: "Output as JSON (default is text).",
   200  			},
   201  			cli.BoolFlag{
   202  				Name:  "v, verbose",
   203  				Usage: "A full dump, with more gory details.",
   204  			},
   205  			cli.StringFlag{
   206  				Name:  "t, type",
   207  				Usage: "Type of sig to output: follow, proof, cryptocurrency, self, all (default is all).",
   208  			},
   209  			cli.BoolFlag{
   210  				Name:  "a, all-keys",
   211  				Usage: "Show signatures from all (replaced) keys.",
   212  			},
   213  			cli.BoolFlag{
   214  				Name:  "H, headers",
   215  				Usage: "Show column headers.",
   216  			},
   217  			cli.StringFlag{
   218  				Name:  "f, filter",
   219  				Usage: "Provide a regex filter.",
   220  			},
   221  		},
   222  	}
   223  }
   224  
   225  func (s *CmdSigsList) GetUsage() libkb.Usage {
   226  	return libkb.Usage{
   227  		Config: true,
   228  		API:    true,
   229  	}
   230  }