180 lines
4.6 KiB
Go
180 lines
4.6 KiB
Go
|
// Copyright (c) HashiCorp, Inc.
|
||
|
// SPDX-License-Identifier: MPL-2.0
|
||
|
|
||
|
package command
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/mitchellh/cli"
|
||
|
"github.com/posener/complete"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
_ cli.Command = (*TokenRevokeCommand)(nil)
|
||
|
_ cli.CommandAutocomplete = (*TokenRevokeCommand)(nil)
|
||
|
)
|
||
|
|
||
|
type TokenRevokeCommand struct {
|
||
|
*BaseCommand
|
||
|
|
||
|
flagAccessor bool
|
||
|
flagSelf bool
|
||
|
flagMode string
|
||
|
}
|
||
|
|
||
|
func (c *TokenRevokeCommand) Synopsis() string {
|
||
|
return "Revoke a token and its children"
|
||
|
}
|
||
|
|
||
|
func (c *TokenRevokeCommand) Help() string {
|
||
|
helpText := `
|
||
|
Usage: vault token revoke [options] [TOKEN | ACCESSOR]
|
||
|
|
||
|
Revokes authentication tokens and their children. If a TOKEN is not provided,
|
||
|
the locally authenticated token is used. The "-mode" flag can be used to
|
||
|
control the behavior of the revocation. See the "-mode" flag documentation
|
||
|
for more information.
|
||
|
|
||
|
Revoke a token and all the token's children:
|
||
|
|
||
|
$ vault token revoke 96ddf4bc-d217-f3ba-f9bd-017055595017
|
||
|
|
||
|
Revoke a token leaving the token's children:
|
||
|
|
||
|
$ vault token revoke -mode=orphan 96ddf4bc-d217-f3ba-f9bd-017055595017
|
||
|
|
||
|
Revoke a token by accessor:
|
||
|
|
||
|
$ vault token revoke -accessor 9793c9b3-e04a-46f3-e7b8-748d7da248da
|
||
|
|
||
|
For a full list of examples, please see the documentation.
|
||
|
|
||
|
` + c.Flags().Help()
|
||
|
|
||
|
return strings.TrimSpace(helpText)
|
||
|
}
|
||
|
|
||
|
func (c *TokenRevokeCommand) Flags() *FlagSets {
|
||
|
set := c.flagSet(FlagSetHTTP)
|
||
|
|
||
|
f := set.NewFlagSet("Command Options")
|
||
|
|
||
|
f.BoolVar(&BoolVar{
|
||
|
Name: "accessor",
|
||
|
Target: &c.flagAccessor,
|
||
|
Default: false,
|
||
|
EnvVar: "",
|
||
|
Completion: complete.PredictNothing,
|
||
|
Usage: "Treat the argument as an accessor instead of a token.",
|
||
|
})
|
||
|
|
||
|
f.BoolVar(&BoolVar{
|
||
|
Name: "self",
|
||
|
Target: &c.flagSelf,
|
||
|
Default: false,
|
||
|
EnvVar: "",
|
||
|
Completion: complete.PredictNothing,
|
||
|
Usage: "Perform the revocation on the currently authenticated token.",
|
||
|
})
|
||
|
|
||
|
f.StringVar(&StringVar{
|
||
|
Name: "mode",
|
||
|
Target: &c.flagMode,
|
||
|
Default: "",
|
||
|
EnvVar: "",
|
||
|
Completion: complete.PredictSet("orphan", "path"),
|
||
|
Usage: "Type of revocation to perform. If unspecified, Vault will revoke " +
|
||
|
"the token and all of the token's children. If \"orphan\", Vault will " +
|
||
|
"revoke only the token, leaving the children as orphans. If \"path\", " +
|
||
|
"tokens created from the given authentication path prefix are deleted " +
|
||
|
"along with their children.",
|
||
|
})
|
||
|
|
||
|
return set
|
||
|
}
|
||
|
|
||
|
func (c *TokenRevokeCommand) AutocompleteArgs() complete.Predictor {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (c *TokenRevokeCommand) AutocompleteFlags() complete.Flags {
|
||
|
return c.Flags().Completions()
|
||
|
}
|
||
|
|
||
|
func (c *TokenRevokeCommand) Run(args []string) int {
|
||
|
f := c.Flags()
|
||
|
|
||
|
if err := f.Parse(args); err != nil {
|
||
|
c.UI.Error(err.Error())
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
args = f.Args()
|
||
|
token := ""
|
||
|
if len(args) > 0 {
|
||
|
token = strings.TrimSpace(args[0])
|
||
|
}
|
||
|
|
||
|
switch c.flagMode {
|
||
|
case "", "orphan", "path":
|
||
|
default:
|
||
|
c.UI.Error(fmt.Sprintf("Invalid mode: %s", c.flagMode))
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
switch {
|
||
|
case c.flagSelf && len(args) > 0:
|
||
|
c.UI.Error(fmt.Sprintf("Too many arguments with -self (expected 0, got %d)", len(args)))
|
||
|
return 1
|
||
|
case !c.flagSelf && len(args) > 1:
|
||
|
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1 or -self, got %d)", len(args)))
|
||
|
return 1
|
||
|
case !c.flagSelf && len(args) < 1:
|
||
|
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1 or -self, got %d)", len(args)))
|
||
|
return 1
|
||
|
case c.flagSelf && c.flagAccessor:
|
||
|
c.UI.Error("Cannot use -self with -accessor!")
|
||
|
return 1
|
||
|
case c.flagSelf && c.flagMode != "":
|
||
|
c.UI.Error("Cannot use -self with -mode!")
|
||
|
return 1
|
||
|
case c.flagAccessor && c.flagMode == "orphan":
|
||
|
c.UI.Error("Cannot use -accessor with -mode=orphan!")
|
||
|
return 1
|
||
|
case c.flagAccessor && c.flagMode == "path":
|
||
|
c.UI.Error("Cannot use -accessor with -mode=path!")
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
client, err := c.Client()
|
||
|
if err != nil {
|
||
|
c.UI.Error(err.Error())
|
||
|
return 2
|
||
|
}
|
||
|
|
||
|
var revokeFn func(string) error
|
||
|
// Handle all 6 possible combinations
|
||
|
switch {
|
||
|
case !c.flagAccessor && c.flagSelf && c.flagMode == "":
|
||
|
revokeFn = client.Auth().Token().RevokeSelf
|
||
|
case !c.flagAccessor && !c.flagSelf && c.flagMode == "":
|
||
|
revokeFn = client.Auth().Token().RevokeTree
|
||
|
case !c.flagAccessor && !c.flagSelf && c.flagMode == "orphan":
|
||
|
revokeFn = client.Auth().Token().RevokeOrphan
|
||
|
case !c.flagAccessor && !c.flagSelf && c.flagMode == "path":
|
||
|
revokeFn = client.Sys().RevokePrefix
|
||
|
case c.flagAccessor && !c.flagSelf && c.flagMode == "":
|
||
|
revokeFn = client.Auth().Token().RevokeAccessor
|
||
|
}
|
||
|
|
||
|
if err := revokeFn(token); err != nil {
|
||
|
c.UI.Error(fmt.Sprintf("Error revoking token: %s", err))
|
||
|
return 2
|
||
|
}
|
||
|
|
||
|
c.UI.Output("Success! Revoked token (if it existed)")
|
||
|
return 0
|
||
|
}
|