user_key_add.go

 1package commands
 2
 3import (
 4	"fmt"
 5
 6	"github.com/MichaelMure/git-bug/cache"
 7	"github.com/MichaelMure/git-bug/identity"
 8	"github.com/MichaelMure/git-bug/input"
 9	"github.com/MichaelMure/git-bug/util/interrupt"
10	"github.com/MichaelMure/git-bug/validate"
11	"github.com/pkg/errors"
12	"github.com/spf13/cobra"
13)
14
15var (
16	keyAddArmoredFile    string
17	keyAddArmored        string
18)
19
20func runKeyAdd(cmd *cobra.Command, args []string) error {
21	backend, err := cache.NewRepoCache(repo)
22	if err != nil {
23		return err
24	}
25	defer backend.Close()
26	interrupt.RegisterCleaner(backend.Close)
27
28	id, args, err := ResolveUser(backend, args)
29	if err != nil {
30		return err
31	}
32
33	if len(args) > 0 {
34		return fmt.Errorf("unexpected arguments: %s", args)
35	}
36
37	if keyAddArmoredFile != "" && keyAddArmored == "" {
38		keyAddArmored, err = input.TextFileInput(keyAddArmoredFile)
39		if err != nil {
40			return err
41		}
42	}
43
44	if keyAddArmoredFile == "" && keyAddArmored == "" {
45		keyAddArmored, err = input.IdentityVersionKeyEditorInput(backend, "")
46		if err == input.ErrEmptyMessage {
47			fmt.Println("Empty PGP key, aborting.")
48			return nil
49		}
50		if err != nil {
51			return err
52		}
53	}
54
55	key, err := identity.NewKey(keyAddArmored)
56	if err != nil {
57		return err
58	}
59
60	validator, err := validate.NewValidator(backend)
61	if err != nil {
62		return errors.Wrap(err, "failed to create validator")
63	}
64	commitHash := validator.KeyCommitHash(key.PublicKey.KeyId)
65	if commitHash != "" {
66		return fmt.Errorf("key id %d is already used by the key introduced in commit %s", key.PublicKey.KeyId, commitHash)
67	}
68
69	err = id.Mutate(func(mutator identity.Mutator) identity.Mutator {
70		mutator.Keys = append(mutator.Keys, key)
71		return mutator
72	})
73	if err != nil {
74		return err
75	}
76
77	return id.Commit()
78}
79
80var keyAddCmd = &cobra.Command{
81	Use:     "add [<user-id>]",
82	Short:   "Add a PGP key from a user.",
83	PreRunE: loadRepoEnsureUser,
84	RunE:    runKeyAdd,
85}
86
87func init() {
88	keyCmd.AddCommand(keyAddCmd)
89
90	keyAddCmd.Flags().SortFlags = false
91
92	keyAddCmd.Flags().StringVarP(&keyAddArmoredFile, "file", "F", "",
93		"Take the armored PGP public key from the given file. Use - to read the message from the standard input",
94	)
95
96	keyAddCmd.Flags().StringVarP(&keyAddArmored, "key", "k", "",
97		"Provide the armored PGP public key from the command line",
98	)
99}