gitlab.com/SkynetLabs/skyd@v1.6.9/cmd/skyc/skykeycmd.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 "text/tabwriter" 8 9 "github.com/spf13/cobra" 10 11 "gitlab.com/NebulousLabs/errors" 12 "gitlab.com/SkynetLabs/skyd/node/api/client" 13 "gitlab.com/SkynetLabs/skyd/skykey" 14 ) 15 16 var ( 17 // errBothNameAndIDUsed is returned if both the Skykey name and ID are 18 // supplied for an operation that requires one or the other 19 errBothNameAndIDUsed = errors.New("Can only use one flag: --name or --id flag") 20 21 // errNeitherNameNorIDUsed is returned if neither the Skykey name or ID are 22 // supplied for an operation that requires one or the other 23 errNeitherNameNorIDUsed = errors.New("Must use either the --name or --id flag") 24 ) 25 var ( 26 skykeyCmd = &cobra.Command{ 27 Use: "skykey", 28 Short: "Perform actions related to Skykeys", 29 Long: `Perform actions related to Skykeys, the encryption keys used for Skyfiles.`, 30 Run: skykeycmd, 31 } 32 33 skykeyAddCmd = &cobra.Command{ 34 Use: "add [skykey base64-encoded skykey]", 35 Short: "Add a base64-encoded skykey to the key manager.", 36 Long: `Add a base64-encoded skykey to the key manager.`, 37 Run: wrap(skykeyaddcmd), 38 } 39 40 skykeyCreateCmd = &cobra.Command{ 41 Use: "create [name]", 42 Short: "Create a skykey with the given name.", 43 Long: `Create a skykey with the given name. The --type flag can be 44 used to specify the skykey type. Its default is private-id.`, 45 Run: wrap(skykeycreatecmd), 46 } 47 48 skykeyDeleteCmd = &cobra.Command{ 49 Use: "delete", 50 Short: "Delete the skykey by name or id", 51 Long: `Delete the base64-encoded skykey using its name or id`, 52 } 53 54 skykeyDeleteNameCmd = &cobra.Command{ 55 Use: "name [name]", 56 Short: "Delete the skykey by name", 57 Long: `Delete the base64-encoded skykey using its name`, 58 Run: wrap(skykeydeletenamecmd), 59 } 60 61 skykeyDeleteIDCmd = &cobra.Command{ 62 Use: "id [id]", 63 Short: "Delete the skykey by id", 64 Long: `Delete the base64-encoded skykey using its id`, 65 Run: wrap(skykeydeleteidcmd), 66 } 67 68 skykeyGetCmd = &cobra.Command{ 69 Use: "get", 70 Short: "Get the skykey by its name or id", 71 Long: `Get the base64-encoded skykey using either its name with --name or id with --id`, 72 Run: wrap(skykeygetcmd), 73 } 74 75 skykeyGetIDCmd = &cobra.Command{ 76 Use: "get-id [name]", 77 Short: "Get the skykey id by its name", 78 Long: `Get the base64-encoded skykey id by its name`, 79 Run: wrap(skykeygetidcmd), 80 } 81 82 skykeyListCmd = &cobra.Command{ 83 Use: "ls", 84 Short: "List all skykeys", 85 Long: "List all skykeys. Use with --show-priv-keys to show full encoding with private key also.", 86 Run: wrap(skykeylistcmd), 87 } 88 ) 89 90 // skykeycmd displays the usage info for the command. 91 func skykeycmd(cmd *cobra.Command, args []string) { 92 _ = cmd.UsageFunc()(cmd) 93 os.Exit(exitCodeUsage) 94 } 95 96 // skykeycreatecmd is a wrapper for skykeyCreate used to handle skykey creation. 97 func skykeycreatecmd(name string) { 98 skykeyStr, err := skykeyCreate(httpClient, name, skykeyType) 99 if err != nil { 100 die(errors.AddContext(err, "Failed to create new skykey")) 101 } 102 fmt.Printf("Created new skykey: %v\n", skykeyStr) 103 } 104 105 // skykeyCreate creates a new Skykey with the given name and cipher type 106 func skykeyCreate(c client.Client, name, skykeyTypeString string) (string, error) { 107 var st skykey.SkykeyType 108 if skykeyTypeString == "" { 109 // If no type is provided, default to Private 110 st = skykey.TypePrivateID 111 } else { 112 err := st.FromString(skykeyTypeString) 113 if err != nil { 114 return "", errors.AddContext(err, "Unable to decode skykey type") 115 } 116 } 117 sk, err := c.SkykeyCreateKeyPost(name, st) 118 if err != nil { 119 return "", errors.AddContext(err, "Could not create skykey") 120 } 121 return sk.ToString() 122 } 123 124 // skykeyaddcmd is a wrapper for skykeyAdd used to handle the addition of new skykeys. 125 func skykeyaddcmd(skykeyString string) { 126 err := skykeyAdd(httpClient, skykeyString) 127 if err != nil && strings.Contains(err.Error(), skykey.ErrSkykeyWithNameAlreadyExists.Error()) { 128 die("Skykey name already used. Try using the --rename-as parameter with a different name.") 129 } 130 if err != nil { 131 die(errors.AddContext(err, "Failed to add skykey")) 132 } 133 134 fmt.Printf("Successfully added new skykey: %v\n", skykeyString) 135 } 136 137 // skykeyAdd adds the given skykey to the renter's skykey manager. 138 func skykeyAdd(c client.Client, skykeyString string) error { 139 var sk skykey.Skykey 140 err := sk.FromString(skykeyString) 141 if err != nil { 142 return errors.AddContext(err, "Could not decode skykey string") 143 } 144 145 // Rename the skykey if the --rename-as flag was provided. 146 if skykeyRenameAs != "" { 147 sk.Name = skykeyRenameAs 148 } 149 150 err = c.SkykeyAddKeyPost(sk) 151 if err != nil { 152 return errors.AddContext(err, "Could not add skykey") 153 } 154 155 return nil 156 } 157 158 // skykeydeleteidcmd is a wrapper for skykeyDeleteID that handles skykey 159 // delete commands. 160 func skykeydeleteidcmd(id string) { 161 var skykeyID skykey.SkykeyID 162 err := skykeyID.FromString(id) 163 if err != nil { 164 die(errors.AddContext(err, "could not decode skykey ID")) 165 } 166 err = httpClient.SkykeyDeleteByIDPost(skykeyID) 167 if err != nil { 168 die(err) 169 } 170 171 fmt.Println("Skykey Deleted!") 172 } 173 174 // skykeydeletenamecmd is a wrapper for skykeyDeleteName that handles skykey 175 // delete commands. 176 func skykeydeletenamecmd(name string) { 177 err := httpClient.SkykeyDeleteByNamePost(name) 178 if err != nil { 179 die(err) 180 } 181 182 fmt.Println("Skykey Deleted!") 183 } 184 185 // skykeygetcmd is a wrapper for skykeyGet that handles skykey get commands. 186 func skykeygetcmd() { 187 skykeyStr, err := skykeyGet(httpClient, skykeyName, skykeyID) 188 if err != nil { 189 die(err) 190 } 191 192 fmt.Printf("Found skykey: %v\n", skykeyStr) 193 } 194 195 // skykeyGet retrieves the skykey using a name or id flag. 196 func skykeyGet(c client.Client, name, id string) (string, error) { 197 err := validateSkyKeyNameAndIDUsage(name, id) 198 if err != nil { 199 return "", errors.AddContext(err, "cannot validate skykey name and ID usage to get skykey") 200 } 201 202 var sk skykey.Skykey 203 if name != "" { 204 sk, err = c.SkykeyGetByName(name) 205 } else { 206 var skykeyID skykey.SkykeyID 207 err = skykeyID.FromString(id) 208 if err != nil { 209 return "", errors.AddContext(err, "Could not decode skykey ID") 210 } 211 sk, err = c.SkykeyGetByID(skykeyID) 212 } 213 214 if err != nil { 215 return "", errors.AddContext(err, "Failed to retrieve skykey") 216 } 217 218 return sk.ToString() 219 } 220 221 // skykeygetidcmd retrieves the skykey id using its name. 222 func skykeygetidcmd(skykeyName string) { 223 sk, err := httpClient.SkykeyGetByName(skykeyName) 224 if err != nil { 225 die("Failed to retrieve skykey:", err) 226 } 227 fmt.Printf("Found skykey ID: %v\n", sk.ID().ToString()) 228 } 229 230 // skykeylistcmd is a wrapper for skykeyListKeys that prints a list of all 231 // skykeys. 232 func skykeylistcmd() { 233 skykeysString, err := skykeyListKeys(httpClient, skykeyShowPrivateKeys) 234 if err != nil { 235 die("Failed to get all skykeys:", err) 236 } 237 fmt.Print(skykeysString) 238 } 239 240 // skykeyListKeys returns a formatted string containing a list of all skykeys 241 // being stored by the renter. It includes IDs, Names, and if showPrivateKeys is 242 // set to true it will include the full encoded skykey. 243 func skykeyListKeys(c client.Client, showPrivateKeys bool) (string, error) { 244 skykeys, err := c.SkykeySkykeysGet() 245 if err != nil { 246 return "", err 247 } 248 249 var b strings.Builder 250 w := tabwriter.NewWriter(&b, 0, 0, 2, ' ', 0) 251 252 // Print a title row. 253 if showPrivateKeys { 254 fmt.Fprintf(w, "ID\tName\tType\tFull Skykey\n") 255 } else { 256 fmt.Fprintf(w, "ID\tName\tType\n") 257 } 258 259 if err = w.Flush(); err != nil { 260 return "", err 261 } 262 titleLen := b.Len() - 1 263 for i := 0; i < titleLen; i++ { 264 fmt.Fprintf(w, "-") 265 } 266 fmt.Fprintf(w, "\n") 267 268 for _, sk := range skykeys { 269 idStr := sk.ID().ToString() 270 if !showPrivateKeys { 271 fmt.Fprintf(w, "%s\t%s\t%s\n", idStr, sk.Name, sk.Type.ToString()) 272 continue 273 } 274 skStr, err := sk.ToString() 275 if err != nil { 276 return "", err 277 } 278 fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", idStr, sk.Name, sk.Type.ToString(), skStr) 279 } 280 281 if err = w.Flush(); err != nil { 282 return "", err 283 } 284 return b.String(), nil 285 }