Jelajahi Sumber

cmd/tailscale/cli: [up] reuse --advertise-tags for OAuth key generation

We need to always specify tags when creating an AuthKey from an OAuth key.

Check for that, and reuse the `--advertise-tags` param.

Updates #7982

Signed-off-by: Maisem Ali <[email protected]>
Maisem Ali 2 tahun lalu
induk
melakukan
a8f10c23b2
1 mengubah file dengan 11 tambahan dan 11 penghapusan
  1. 11 11
      cmd/tailscale/cli/up.go

+ 11 - 11
cmd/tailscale/cli/up.go

@@ -668,7 +668,7 @@ func runUp(ctx context.Context, cmd string, args []string, upArgs upArgsT) (retE
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		authKey, err = resolveAuthKey(ctx, authKey)
+		authKey, err = resolveAuthKey(ctx, authKey, upArgs.advertiseTags)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -1121,19 +1121,23 @@ func init() {
 // resolveAuthKey either returns v unchanged (in the common case) or, if it
 // resolveAuthKey either returns v unchanged (in the common case) or, if it
 // starts with "tskey-client-" (as Tailscale OAuth secrets do) parses it like
 // starts with "tskey-client-" (as Tailscale OAuth secrets do) parses it like
 //
 //
-//	tskey-client-xxxx[?ephemeral=false&tags=foo,bar&preauthorized=BOOL&baseURL=...]
+//	tskey-client-xxxx[?ephemeral=false&bar&preauthorized=BOOL&baseURL=...]
 //
 //
 // and does the OAuth2 dance to get and return an authkey. The "ephemeral"
 // and does the OAuth2 dance to get and return an authkey. The "ephemeral"
 // property defaults to true if unspecified. The "preauthorized" defaults to
 // property defaults to true if unspecified. The "preauthorized" defaults to
-// false. The "baseURL" defaults to
-// https://api.tailscale.com.
-func resolveAuthKey(ctx context.Context, v string) (string, error) {
+// false. The "baseURL" defaults to https://api.tailscale.com.
+// The passed in tags are required, and must be non-empty. These will be
+// set on the authkey generated by the OAuth2 dance.
+func resolveAuthKey(ctx context.Context, v, tags string) (string, error) {
 	if !strings.HasPrefix(v, "tskey-client-") {
 	if !strings.HasPrefix(v, "tskey-client-") {
 		return v, nil
 		return v, nil
 	}
 	}
 	if !envknob.Bool("TS_EXPERIMENT_OAUTH_AUTHKEY") {
 	if !envknob.Bool("TS_EXPERIMENT_OAUTH_AUTHKEY") {
 		return "", errors.New("oauth authkeys are in experimental status")
 		return "", errors.New("oauth authkeys are in experimental status")
 	}
 	}
+	if tags == "" {
+		return "", errors.New("oauth authkeys require --advertise-tags")
+	}
 
 
 	clientSecret, named, _ := strings.Cut(v, "?")
 	clientSecret, named, _ := strings.Cut(v, "?")
 	attrs, err := url.ParseQuery(named)
 	attrs, err := url.ParseQuery(named)
@@ -1142,7 +1146,7 @@ func resolveAuthKey(ctx context.Context, v string) (string, error) {
 	}
 	}
 	for k := range attrs {
 	for k := range attrs {
 		switch k {
 		switch k {
-		case "ephemeral", "preauthorized", "tags", "baseURL":
+		case "ephemeral", "preauthorized", "baseURL":
 		default:
 		default:
 			return "", fmt.Errorf("unknown attribute %q", k)
 			return "", fmt.Errorf("unknown attribute %q", k)
 		}
 		}
@@ -1166,10 +1170,6 @@ func resolveAuthKey(ctx context.Context, v string) (string, error) {
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	var tags []string
-	if v := attrs.Get("tags"); v != "" {
-		tags = strings.Split(v, ",")
-	}
 
 
 	baseURL := "https://api.tailscale.com"
 	baseURL := "https://api.tailscale.com"
 	if v := attrs.Get("baseURL"); v != "" {
 	if v := attrs.Get("baseURL"); v != "" {
@@ -1193,7 +1193,7 @@ func resolveAuthKey(ctx context.Context, v string) (string, error) {
 				Reusable:      false,
 				Reusable:      false,
 				Ephemeral:     ephemeral,
 				Ephemeral:     ephemeral,
 				Preauthorized: preauth,
 				Preauthorized: preauth,
-				Tags:          tags,
+				Tags:          strings.Split(tags, ","),
 			},
 			},
 		},
 		},
 	}
 	}