diff --git a/api.go b/api.go index 13955d39..0aad5ee9 100644 --- a/api.go +++ b/api.go @@ -395,6 +395,9 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, m.RegisterMethod = "authKey" db.Save(&m) + pak.Used = true + db.Save(&pak) + resp.MachineAuthorized = true resp.User = *pak.Namespace.toUser() respBody, err := encode(resp, &idKey, h.privateKey) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 5f30dc1b..c01bce9a 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -129,6 +129,7 @@ var deleteNodeCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { + output, _ := cmd.Flags().GetString("output") h, err := getHeadscaleApp() if err != nil { log.Fatalf("Error initializing: %s", err) @@ -153,11 +154,19 @@ var deleteNodeCmd = &cobra.Command{ if confirm { err = h.DeleteMachine(m) + if strings.HasPrefix(output, "json") { + JsonOutput(map[string]string{"Result": "Node deleted"}, err, output) + return + } if err != nil { log.Fatalf("Error deleting node: %s", err) } fmt.Printf("Node deleted\n") } else { + if strings.HasPrefix(output, "json") { + JsonOutput(map[string]string{"Result": "Node not deleted"}, err, output) + return + } fmt.Printf("Node not deleted\n") } }, diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 1340267e..cb75b287 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -57,7 +57,7 @@ var listPreAuthKeys = &cobra.Command{ return } - d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Expiration", "Created"}} + d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}} for _, k := range *keys { expiration := "-" if k.Expiration != nil { @@ -76,6 +76,7 @@ var listPreAuthKeys = &cobra.Command{ k.Key, reusable, strconv.FormatBool(k.Ephemeral), + fmt.Sprintf("%v", k.Used), expiration, k.CreatedAt.Format("2006-01-02 15:04:05"), }) diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index f879f91e..95555e94 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -262,3 +262,12 @@ func JsonOutput(result interface{}, errResult error, outputFormat string) { } fmt.Println(string(j)) } + +func HasJsonOutputFlag() bool { + for _, arg := range os.Args { + if arg == "json" || arg == "json-line" { + return true + } + } + return false +} diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index f815001e..6b1a8437 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -62,7 +62,8 @@ func main() { zerolog.SetGlobalLevel(zerolog.DebugLevel) } - if !viper.GetBool("disable_check_updates") { + jsonOutput := cli.HasJsonOutputFlag() + if !viper.GetBool("disable_check_updates") && !jsonOutput { if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && cli.Version != "dev" { githubTag := &latest.GithubTag{ Owner: "juanfont", diff --git a/preauth_keys.go b/preauth_keys.go index cc849fc0..de10cdb7 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -11,7 +11,7 @@ import ( const errorAuthKeyNotFound = Error("AuthKey not found") const errorAuthKeyExpired = Error("AuthKey expired") -const errorAuthKeyNotReusableAlreadyUsed = Error("AuthKey not reusable already used") +const errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") // PreAuthKey describes a pre-authorization key usable in a particular namespace type PreAuthKey struct { @@ -21,6 +21,7 @@ type PreAuthKey struct { Namespace Namespace Reusable bool Ephemeral bool `gorm:"default:false"` + Used bool `gorm:"default:false"` CreatedAt *time.Time Expiration *time.Time @@ -110,11 +111,10 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { return nil, err } - if len(machines) != 0 { - return nil, errorAuthKeyNotReusableAlreadyUsed + if len(machines) != 0 || pak.Used { + return nil, errSingleUseAuthKeyHasBeenUsed } - // missing here validation on current usage return &pak, nil } diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 37f2e4dd..f8973eaf 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -87,7 +87,7 @@ func (*Suite) TestAlreadyUsedKey(c *check.C) { h.db.Save(&m) p, err := h.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errorAuthKeyNotReusableAlreadyUsed) + c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) c.Assert(p, check.IsNil) } @@ -180,3 +180,16 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(err, check.Equals, errorAuthKeyExpired) c.Assert(p, check.IsNil) } + +func (*Suite) TestNotReusableMarkedAsUsed(c *check.C) { + n, err := h.CreateNamespace("test6") + c.Assert(err, check.IsNil) + + pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + c.Assert(err, check.IsNil) + pak.Used = true + h.db.Save(&pak) + + _, err = h.checkKeyValidity(pak.Key) + c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) +}