repos / pico

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

commit
1bb6dd5
parent
d08b816
author
Eric Bower
date
2024-11-30 19:02:40 +0000 UTC
feat(pico): impersonation
6 files changed,  +40, -8
M tui/common/model.go
+1, -0
1@@ -19,4 +19,5 @@ type SharedModel struct {
2 	Height          int
3 	HeaderHeight    int
4 	Styles          Styles
5+	Impersonated    bool
6 }
M tui/mdw.go
+4, -0
 1@@ -36,6 +36,10 @@ func CmsMiddleware(cfg *shared.ConfigSite) bm.Handler {
 2 		}
 3 
 4 		m := NewUI(shrd)
 5+		err := m.setupUser()
 6+		if err != nil {
 7+			return nil, nil
 8+		}
 9 
10 		opts := bm.MakeOptions(sesh)
11 		opts = append(opts, tea.WithAltScreen())
M tui/menu/menu.go
+4, -0
 1@@ -130,6 +130,10 @@ func (m Model) bioView() string {
 2 		vals = append(vals, "Pico+ Expires", expires)
 3 	}
 4 
 5+	if m.shared.Impersonated {
 6+		vals = append(vals, "Impersonated", "YES")
 7+	}
 8+
 9 	return common.KeyValueView(m.shared.Styles, vals...)
10 }
11 
M tui/pubkeys/keys.go
+1, -1
1@@ -161,7 +161,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
2 		m.index = 0
3 		m.keys = msg
4 		for i, key := range m.keys {
5-			if key.Key == m.shared.User.PublicKey.Key {
6+			if m.shared.User.PublicKey != nil && key.Key == m.shared.User.PublicKey.Key {
7 				m.activeKeyIndex = i
8 			}
9 		}
M tui/ui.go
+14, -7
 1@@ -54,20 +54,26 @@ func (m *UI) updateActivePage(msg tea.Msg) tea.Cmd {
 2 	return cmd
 3 }
 4 
 5-func (m *UI) Init() tea.Cmd {
 6-	// header height is required to calculate viewport for
 7-	// some pages
 8-	m.shared.HeaderHeight = lipgloss.Height(m.header()) + 1
 9+func (m *UI) setupUser() error {
10 	user, err := findUser(m.shared)
11 	if err != nil {
12-		wish.Errorln(m.shared.Session, err)
13-		return tea.Quit
14+		m.shared.Logger.Error("cannot find user", "err", err)
15+		wish.Errorf(m.shared.Session, "\nERROR: %s\n\n", err)
16+		return err
17 	}
18-	m.shared.User = user
19 
20+	m.shared.User = user
21 	ff, _ := findPlusFeatureFlag(m.shared)
22 	m.shared.PlusFeatureFlag = ff
23 
24+	return nil
25+}
26+
27+func (m *UI) Init() tea.Cmd {
28+	// header height is required to calculate viewport for
29+	// some pages
30+	m.shared.HeaderHeight = lipgloss.Height(m.header()) + 1
31+
32 	m.pages[pages.MenuPage] = menu.NewModel(m.shared)
33 	m.pages[pages.CreateAccountPage] = createaccount.NewModel(m.shared)
34 	m.pages[pages.CreatePubkeyPage] = createkey.NewModel(m.shared)
35@@ -126,6 +132,7 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
36 
37 	// user created account
38 	case createaccount.CreateAccountMsg:
39+		_ = m.setupUser()
40 		// reset model and pages
41 		return m, m.Init()
42 
M tui/util.go
+16, -0
 1@@ -3,6 +3,7 @@ package tui
 2 import (
 3 	"errors"
 4 	"fmt"
 5+	"strings"
 6 
 7 	"github.com/picosh/pico/db"
 8 	"github.com/picosh/pico/tui/common"
 9@@ -31,6 +32,21 @@ func findUser(shrd *common.SharedModel) (*db.User, error) {
10 		return nil, nil
11 	}
12 
13+	// impersonation
14+	adminPrefix := "admin__"
15+	if strings.HasPrefix(usr, adminPrefix) {
16+		hasFeature := shrd.Dbpool.HasFeatureForUser(user.ID, "admin")
17+		if !hasFeature {
18+			return nil, fmt.Errorf("only admins can impersonate a user")
19+		}
20+		impersonate := strings.Replace(usr, adminPrefix, "", 1)
21+		user, err = shrd.Dbpool.FindUserForName(impersonate)
22+		if err != nil {
23+			return nil, err
24+		}
25+		shrd.Impersonated = true
26+	}
27+
28 	return user, nil
29 }
30