diff --git a/api/http.go b/api/http.go index b4215b0..6075e3f 100644 --- a/api/http.go +++ b/api/http.go @@ -35,16 +35,11 @@ func NewHTTPServer(cfg *gpaste.ServerConfig) *HTTPServer { config: cfg, Logger: zap.NewNop().Sugar(), AccessLogger: zap.NewNop().Sugar(), + Files: files.NewMemoryFileStore(), + Users: users.NewMemoryUserStore(), } - srv.Files = files.NewMemoryFileStore() - srv.Users = users.NewMemoryUserStore() - srv.Auth = gpaste.NewAuthService(srv.Users, []byte(srv.config.SigningSecret)) - - // Create initial user - // TODO: Do properly - user := &users.User{Username: "admin", Role: users.RoleAdmin} - _ = user.SetPassword("admin") - _ = srv.Users.Store(user) + signingSecret, _ := uuid.Must(uuid.NewRandom()).MarshalBinary() + srv.Auth = gpaste.NewAuthService(srv.Users, signingSecret) r := chi.NewRouter() r.Use(middleware.RealIP) diff --git a/cmd/server/actions/actions.go b/cmd/server/actions/actions.go index bc2d72a..f409407 100644 --- a/cmd/server/actions/actions.go +++ b/cmd/server/actions/actions.go @@ -6,11 +6,15 @@ import ( "net/http" "os" "os/signal" + "path/filepath" "strings" "time" "git.t-juice.club/torjus/gpaste" "git.t-juice.club/torjus/gpaste/api" + "git.t-juice.club/torjus/gpaste/files" + "git.t-juice.club/torjus/gpaste/users" + "github.com/google/uuid" "github.com/urfave/cli/v2" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -62,11 +66,49 @@ func ActionServe(c *cli.Context) error { httpShutdownCtx, httpShutdownCancel := context.WithCancel(context.Background()) defer httpShutdownCancel() + // Setup stores + // Files + fileStore, fileClose, err := getFileStore(cfg) + if err != nil { + return err + } + + defer fileClose() // nolint: errcheck + + // Users + userStore, userClose, err := getUserStore(cfg) + if err != nil { + return err + } + + defer userClose() // nolint: errcheck + + if userList, err := userStore.List(); err != nil { + serverLogger.Panicw("Error checking userstore for users.", "error", err) + } else if len(userList) < 1 { + admin := users.User{ + Username: "admin", + Role: users.RoleAdmin, + } + password := uuid.NewString() + if err := admin.SetPassword(password); err != nil { + serverLogger.DPanic("Error setting admin-user password.", "error", err) + } + + serverLogger.Warnw("Created admin-user.", "username", admin.Username, "password", password) + } + + // Auth + auth := gpaste.NewAuthService(userStore, []byte(cfg.SigningSecret)) + go func() { srv := api.NewHTTPServer(cfg) + srv.Users = userStore + srv.Files = fileStore srv.Addr = cfg.ListenAddr srv.Logger = serverLogger srv.AccessLogger = accessLogger + srv.Auth = auth // Wait for cancel go func() { @@ -126,3 +168,48 @@ func getRootLogger(level string) *zap.SugaredLogger { return rootLogger.Sugar() } + +// nolint: ireturn +func getUserStore(cfg *gpaste.ServerConfig) (users.UserStore, func() error, error) { + closer := func() error { return nil } + + switch cfg.Store.Type { + case "memory": + return users.NewMemoryUserStore(), closer, nil + + case "fs": + path := filepath.Join(cfg.Store.FS.Dir, "gpaste-users.db") + + bs, err := users.NewBoltUserStore(path) + if err != nil { + return nil, closer, cli.Exit("error setting up user store", 1) + } + + return bs, bs.Close, nil + + default: + return nil, closer, cli.Exit("no userstore configured", 1) + } +} + +// nolint: ireturn +func getFileStore(cfg *gpaste.ServerConfig) (files.FileStore, func() error, error) { + closer := func() error { return nil } + + switch cfg.Store.Type { + case "memory": + return files.NewMemoryFileStore(), closer, nil + + case "fs": + var err error + + s, err := files.NewFSFileStore(cfg.Store.FS.Dir) + if err != nil { + return nil, closer, cli.Exit("error setting up filestore", 1) + } + + return s, closer, nil + default: + return nil, closer, cli.Exit("No store configured", 1) + } +}