repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

pico / shared
Eric Bower · 11 Dec 24

ssh.go

 1package shared
 2
 3import (
 4	"log/slog"
 5
 6	"github.com/charmbracelet/ssh"
 7	"github.com/picosh/pico/db"
 8	"github.com/picosh/utils"
 9)
10
11type SshAuthHandler struct {
12	DBPool db.DB
13	Logger *slog.Logger
14	Cfg    *ConfigSite
15}
16
17func NewSshAuthHandler(dbpool db.DB, logger *slog.Logger, cfg *ConfigSite) *SshAuthHandler {
18	return &SshAuthHandler{
19		DBPool: dbpool,
20		Logger: logger,
21		Cfg:    cfg,
22	}
23}
24
25func FindPlusFF(dbpool db.DB, cfg *ConfigSite, userID string) *db.FeatureFlag {
26	ff, _ := dbpool.FindFeatureForUser(userID, "plus")
27	// we have free tiers so users might not have a feature flag
28	// in which case we set sane defaults
29	if ff == nil {
30		ff = db.NewFeatureFlag(
31			userID,
32			"plus",
33			cfg.MaxSize,
34			cfg.MaxAssetSize,
35			cfg.MaxSpecialFileSize,
36		)
37	}
38	// this is jank
39	ff.Data.StorageMax = ff.FindStorageMax(cfg.MaxSize)
40	ff.Data.FileMax = ff.FindFileMax(cfg.MaxAssetSize)
41	ff.Data.SpecialFileMax = ff.FindSpecialFileMax(cfg.MaxSpecialFileSize)
42	return ff
43}
44
45func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool {
46	pubkey := utils.KeyForKeyText(key)
47	user, err := r.DBPool.FindUserForKey(ctx.User(), pubkey)
48	if err != nil {
49		r.Logger.Error(
50			"could not find user for key",
51			"key", key,
52			"err", err,
53		)
54		return false
55	}
56
57	if user.Name == "" {
58		r.Logger.Error("username is not set")
59		return false
60	}
61
62	if ctx.Permissions().Extensions == nil {
63		ctx.Permissions().Extensions = map[string]string{}
64	}
65	ctx.Permissions().Extensions["user_id"] = user.ID
66	ctx.Permissions().Extensions["pubkey"] = pubkey
67	return true
68}