repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

commit
8c838e2
parent
5403c06
author
Eric Bower
date
2025-07-13 09:20:13 -0400 EDT
feat(pgs): self hosted init cmd
5 files changed,  +70, -15
M cmd/pgs/standalone/main.go
+31, -0
 1@@ -1,11 +1,15 @@
 2 package main
 3 
 4 import (
 5+	"os"
 6+	"strings"
 7+
 8 	"github.com/picosh/pico/pkg/apps/pgs"
 9 	pgsdb "github.com/picosh/pico/pkg/apps/pgs/db"
10 	"github.com/picosh/pico/pkg/shared"
11 	"github.com/picosh/pico/pkg/shared/storage"
12 	"github.com/picosh/utils"
13+	"golang.org/x/crypto/ssh"
14 )
15 
16 func main() {
17@@ -27,6 +31,33 @@ func main() {
18 	cfg := pgs.NewPgsConfig(logger, dbpool, st, pubsub)
19 	killCh := make(chan error)
20 
21+	// first time user experience flow
22+	args := os.Args
23+	if len(args) > 0 {
24+		if args[1] == "init" {
25+			if len(args) < 4 {
26+				panic("must provide username and pubkey")
27+			}
28+
29+			userName := args[2]
30+			pubkeyRaw := strings.Join(args[3:], " ")
31+			key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubkeyRaw))
32+			if err != nil {
33+				logger.Error("parse pubkey", "err", err)
34+				return
35+			}
36+			pubkey := utils.KeyForKeyText(key)
37+			logger.Info("init cli", "userName", userName, "pubkey", pubkey)
38+
39+			err = dbpool.RegisterAdmin(userName, pubkey)
40+			if err != nil {
41+				panic(err)
42+			}
43+			logger.Info("Admin user created. You can now start using pgs!")
44+			return
45+		}
46+	}
47+
48 	go pgs.StartApiServer(cfg)
49 	pgs.StartSshServer(cfg, killCh)
50 }
M pkg/apps/pgs/cli_middleware.go
+11, -15
 1@@ -67,29 +67,25 @@ func Middleware(handler *UploadAssetHandler) pssh.SSHServerMiddleware {
 2 				height = pty.Window.Height
 3 			}
 4 
 5-			user, err := getUser(sesh, dbpool)
 6-			if err != nil {
 7-				sendutils.ErrorHandler(sesh, err)
 8-				return err
 9-			}
10-
11-			// renderer := bm.MakeRenderer(sesh)
12-			// renderer.SetColorProfile(termenv.TrueColor)
13-			// styles := common.DefaultStyles(renderer)
14-
15 			opts := Cmd{
16 				Session: sesh,
17-				User:    user,
18 				Store:   store,
19 				Log:     log,
20 				Dbpool:  dbpool,
21 				Write:   false,
22-				// Styles:  styles,
23-				Width:  width,
24-				Height: height,
25-				Cfg:    handler.Cfg,
26+				Width:   width,
27+				Height:  height,
28+				Cfg:     handler.Cfg,
29 			}
30 
31+			user, err := getUser(sesh, dbpool)
32+			if err != nil {
33+				sendutils.ErrorHandler(sesh, err)
34+				return err
35+			}
36+
37+			opts.User = user
38+
39 			if len(args) == 0 {
40 				opts.help()
41 				return nil
M pkg/apps/pgs/db/db.go
+2, -0
1@@ -22,5 +22,7 @@ type PgsDB interface {
2 	FindProjectsByPrefix(userID, name string) ([]*db.Project, error)
3 	FindProjects(by string) ([]*db.Project, error)
4 
5+	RegisterAdmin(username string, pubkey string) error
6+
7 	Close() error
8 }
M pkg/apps/pgs/db/memory.go
+4, -0
1@@ -187,3 +187,7 @@ func (me *MemoryDB) FindProjects(userID string) ([]*db.Project, error) {
2 func (me *MemoryDB) UpdateProjectAcl(userID, name string, acl db.ProjectAcl) error {
3 	return errNotImpl
4 }
5+
6+func (me *MemoryDB) RegisterAdmin(username, pubkey string) error {
7+	return errNotImpl
8+}
M pkg/apps/pgs/db/postgres.go
+22, -0
 1@@ -240,3 +240,25 @@ func (me *PgsPsqlDB) UpdateProjectAcl(userID, name string, acl db.ProjectAcl) er
 2 	)
 3 	return err
 4 }
 5+
 6+func (me *PgsPsqlDB) RegisterAdmin(username, pubkey string) error {
 7+	var userID string
 8+	row := me.Db.QueryRow("INSERT INTO app_users (name) VALUES ($1) RETURNING id", username)
 9+	err := row.Scan(&userID)
10+	if err != nil {
11+		return err
12+	}
13+
14+	_, err = me.Db.Exec("INSERT INTO public_keys (user_id, name, public_key) VALUES ($1, 'main', $2)", userID, pubkey)
15+	if err != nil {
16+		return err
17+	}
18+
19+	_, err = me.Db.Exec("INSERT INTO feature_flags (user_id, name, expires_at) VALUES (1, 'plus', '2100-01-01')", userID)
20+	if err != nil {
21+		return err
22+	}
23+
24+	_, err = me.Db.Exec("INSERT INTO feature_flags (user_id, name, expires_at) VALUES (1, 'admin', '2100-01-01')", userID)
25+	return err
26+}