Parent directory

settings.go

3580 bytes
  1package cmd
  2
  3import (
  4	"fmt"
  5	"strconv"
  6
  7	"github.com/charmbracelet/soft-serve/pkg/access"
  8	"github.com/charmbracelet/soft-serve/pkg/backend"
  9	"github.com/charmbracelet/soft-serve/pkg/config"
 10	"github.com/spf13/cobra"
 11)
 12
 13// SettingsCommand returns a command that manages server settings.
 14func SettingsCommand() *cobra.Command {
 15	cmd := &cobra.Command{
 16		Use:   "settings",
 17		Short: "Manage server settings",
 18		// Gate the whole command tree rather than each subcommand. Cobra
 19		// runs the nearest persistent pre-run found when walking up from
 20		// the invoked command, so subcommands added later are gated by
 21		// default instead of silently unprotected.
 22		PersistentPreRunE: checkIfServerAdmin,
 23	}
 24
 25	cmd.AddCommand(
 26		&cobra.Command{
 27			Use:   "allow-keyless [true|false]",
 28			Short: "Set or get allow keyless access to repositories",
 29			Args:  cobra.RangeArgs(0, 1),
 30			RunE: func(cmd *cobra.Command, args []string) error {
 31				ctx := cmd.Context()
 32				be := backend.FromContext(ctx)
 33				cfg := config.FromContext(ctx)
 34				switch len(args) {
 35				case 0:
 36					cmd.Println(be.AllowKeyless(ctx))
 37				case 1:
 38					v, _ := strconv.ParseBool(args[0])
 39					if err := be.SetAllowKeyless(ctx, v); err != nil {
 40						return err
 41					}
 42					warnIfAllowKeylessOverridden(cmd, cfg)
 43				}
 44
 45				return nil
 46			},
 47		},
 48	)
 49
 50	als := []string{access.NoAccess.String(), access.ReadOnlyAccess.String(), access.ReadWriteAccess.String(), access.AdminAccess.String()}
 51	cmd.AddCommand(
 52		&cobra.Command{
 53			Use:       "anon-access [ACCESS_LEVEL]",
 54			Short:     "Set or get the default access level for anonymous users",
 55			Args:      cobra.RangeArgs(0, 1),
 56			ValidArgs: als,
 57			RunE: func(cmd *cobra.Command, args []string) error {
 58				ctx := cmd.Context()
 59				be := backend.FromContext(ctx)
 60				cfg := config.FromContext(ctx)
 61				switch len(args) {
 62				case 0:
 63					cmd.Println(be.AnonAccess(ctx))
 64				case 1:
 65					al := access.ParseAccessLevel(args[0])
 66					if al < 0 {
 67						return fmt.Errorf("invalid access level: %s. Please choose one of the following: %s", args[0], als)
 68					}
 69					if err := be.SetAnonAccess(ctx, al); err != nil {
 70						return err
 71					}
 72					warnIfAnonAccessOverridden(cmd, cfg)
 73				}
 74
 75				return nil
 76			},
 77		},
 78	)
 79
 80	return cmd
 81}
 82
 83// warnIfAllowKeylessOverridden warns on the command's stderr if a server
 84// config override is masking the allow-keyless value that was just written
 85// to the database. Without this, an admin changing the setting via this
 86// command would have no way to know their change has no effect.
 87func warnIfAllowKeylessOverridden(cmd *cobra.Command, cfg *config.Config) {
 88	if cfg == nil || cfg.AllowKeyless == nil {
 89		return
 90	}
 91
 92	fmt.Fprintf(cmd.ErrOrStderr(),
 93		"Warning: allow-keyless is set to %t by server config and takes precedence over this change. "+
 94			"The database was updated, but it will have no effect until the config override is removed.\n",
 95		*cfg.AllowKeyless)
 96}
 97
 98// warnIfAnonAccessOverridden warns on the command's stderr if a server
 99// config override is masking the anon-access value that was just written to
100// the database. Without this, an admin changing the setting via this
101// command would have no way to know their change has no effect.
102func warnIfAnonAccessOverridden(cmd *cobra.Command, cfg *config.Config) {
103	if cfg == nil || cfg.AnonAccess == nil {
104		return
105	}
106
107	fmt.Fprintf(cmd.ErrOrStderr(),
108		"Warning: anon-access is set to %q by server config and takes precedence over this change. "+
109			"The database was updated, but it will have no effect until the config override is removed.\n",
110		cfg.AnonAccess.String())
111}