Skip to content

Commit

Permalink
improve extensions UX
Browse files Browse the repository at this point in the history
  • Loading branch information
C-Sto committed Oct 8, 2023
1 parent 4421ec1 commit c02c40c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 22 deletions.
10 changes: 10 additions & 0 deletions client/command/extensions/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,13 @@ func ExtensionsCommandNameCompleter(con *console.SliverConsoleClient) carapace.A
return carapace.ActionValuesDescribed(results...).Tag("extension commands")
})
}

func ManifestCompleter() carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
results := []string{}
for k := range loadedManifests {
results = append(results, k)
}
return carapace.ActionValues(results...).Tag("extensions")
})
}
56 changes: 52 additions & 4 deletions client/command/extensions/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,61 @@ func ExtensionRegisterCommand(extCmd *ExtCommand, cmd *cobra.Command, con *conso
}

loadedExtensions[extCmd.CommandName] = extCmd
helpMsg := extCmd.Help
//helpMsg := extCmd.Help

usage := strings.Builder{}
usage.WriteString(extCmd.CommandName)
//build usage including args
for _, arg := range extCmd.Arguments {
usage.WriteString(" ")
if arg.Optional {
usage.WriteString("[")
}
usage.WriteString(strings.ToUpper(arg.Name))
if arg.Optional {
usage.WriteString("]")
}
}
longHelp := strings.Builder{}
//prepend the help value, because otherwise I don't see where it is meant to be shown
//build the command ref
longHelp.WriteString("[[.Bold]]Command:[[.Normal]]")
longHelp.WriteString(usage.String())
longHelp.WriteString("\n")
if len(extCmd.Help) > 0 || len(extCmd.LongHelp) > 0 {
longHelp.WriteString("[[.Bold]]About:[[.Normal]]")
if len(extCmd.Help) > 0 {
longHelp.WriteString(extCmd.Help)
longHelp.WriteString("\n")
}
if len(extCmd.LongHelp) > 0 {
longHelp.WriteString(extCmd.LongHelp)
longHelp.WriteString("\n")
}
}
if len(extCmd.Arguments) > 0 {
longHelp.WriteString("[[.Bold]]Arguments:[[.Normal]]")
}
//if more than 0 args specified, describe each arg at the bottom of the long help text (incase the manifest doesn't include it)
for _, arg := range extCmd.Arguments {
longHelp.WriteString("\n\t")
optStr := ""
if arg.Optional {
optStr = "[OPTIONAL]"
}
aType := arg.Type
if aType == "wstring" {
aType = "string" //avoid confusion, as this is mostly for telling operator what to shove into the args
}
//idk how to make this look nice, tabs don't work especially good - maybe should use the table stuff other things do? Pls help.
longHelp.WriteString(fmt.Sprintf("%s (%s):\t%s%s", strings.ToUpper(arg.Name), aType, optStr, arg.Desc))
}

// Command
extensionCmd := &cobra.Command{
Use: extCmd.CommandName,
Short: helpMsg,
Long: help.FormatHelpTmpl(extCmd.LongHelp),
Use: usage.String(), //extCmd.CommandName,
//Short: helpMsg.String(), doesn't appear to be used?
Long: help.FormatHelpTmpl(longHelp.String()),
Run: func(cmd *cobra.Command, args []string) {
runExtensionCmd(cmd, con, args)
},
Expand Down
39 changes: 21 additions & 18 deletions client/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,22 +160,26 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
}
server.AddCommand(extCmd)

extLoadCmd := &cobra.Command{
Use: consts.LoadStr + " [EXT]",
Short: "Load a command EXT",
Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.LoadStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
extensions.ExtensionLoadCmd(cmd, con, args)
},
}
carapace.Gen(extLoadCmd).PositionalCompletion(
carapace.ActionDirectories().Tag("ext directory").Usage("path to the ext directory"))
extCmd.AddCommand(extLoadCmd)
/*
parking 'load' for now - the difference between 'load' and 'install' is that 'load' should not move binaries and manifests to the client install dir.
Maybe we can revisit this if it's required - but the usecase I can think of is when developing extensions, and that will also occasionally require a manifest update
// extLoadCmd := &cobra.Command{
// Use: consts.LoadStr + " [EXT]",
// Short: "Load a command EXT",
// Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.LoadStr}),
// Args: cobra.ExactArgs(1),
// Run: func(cmd *cobra.Command, args []string) {
// extensions.ExtensionLoadCmd(cmd, con, args)
// },
// }
// carapace.Gen(extLoadCmd).PositionalCompletion(
// carapace.ActionDirectories().Tag("ext directory").Usage("path to the ext directory"))
// extCmd.AddCommand(extLoadCmd)
*/

extInstallCmd := &cobra.Command{
Use: consts.InstallStr + " [EXT]",
Short: "Install a command ext",
Use: consts.InstallStr + " [filepath]",
Short: "Install an extension from a local directory/file.",
Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.InstallStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -186,16 +190,15 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
extCmd.AddCommand(extInstallCmd)

extendo := &cobra.Command{
Use: consts.RmStr + " [EXT]",
Short: "Remove an ext",
Use: consts.RmStr + " [Name]",
Short: "Remove extension. Will remove all commands associated with the installed extension. Does not unload the extension from implants that have already loaded it, but removes the command from the client.",
Long: help.GetHelpFor([]string{consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
//alias.AliasesRemoveCmd(cmd, con, args)
extensions.ExtensionsRemoveCmd(cmd, con, args)
},
}
carapace.Gen(extendo).PositionalCompletion(carapace.ActionFiles().Tag("ext I guess?"))
carapace.Gen(extendo).PositionalCompletion(extensions.ManifestCompleter())
extCmd.AddCommand(extendo)

// [ Armory ] ---------------------------------------------
Expand Down

0 comments on commit c02c40c

Please sign in to comment.