- commit
- c9b9480
- parent
- 3d03d7b
- author
- Antonio Mika
- date
- 2024-10-11 16:21:28 +0000 UTC
Merge pull request #147 from picosh/am/light-refactor Refactor pubsub->pipe
45 files changed,
+285,
-397
M
Makefile
+16,
-16
1@@ -146,19 +146,19 @@ AUTH_DOMAIN=http://auth.dev.pico.sh:3006
2 AUTH_ISSUER=pico.sh
3 AUTH_WEB_PORT=3000
4
5-PUBSUB_CADDYFILE=./caddy/Caddyfile
6-PUBSUB_V4=
7-PUBSUB_V6=
8-PUBSUB_HTTP_V4=$PUBSUB_V4:80
9-PUBSUB_HTTP_V6=[$PUBSUB_V6]:80
10-PUBSUB_HTTPS_V4=$PUBSUB_V4:443
11-PUBSUB_HTTPS_V6=[$PUBSUB_V6]:443
12-PUBSUB_SSH_V4=$PUBSUB_V4:22
13-PUBSUB_SSH_V6=[$PUBSUB_V6]:22
14-PUBSUB_HOST=
15-PUBSUB_SSH_PORT=2222
16-PUBSUB_WEB_PORT=3000
17-PUBSUB_PROM_PORT=9222
18-PUBSUB_DOMAIN=pubsub.dev.pico.sh:3001
19-PUBSUB_PROTOCOL=http
20-PUBSUB_DEBUG=1
21+PIPE_CADDYFILE=./caddy/Caddyfile
22+PIPE_V4=
23+PIPE_V6=
24+PIPE_HTTP_V4=$PIPE_V4:80
25+PIPE_HTTP_V6=[$PIPE_V6]:80
26+PIPE_HTTPS_V4=$PIPE_V4:443
27+PIPE_HTTPS_V6=[$PIPE_V6]:443
28+PIPE_SSH_V4=$PIPE_V4:22
29+PIPE_SSH_V6=[$PIPE_V6]:22
30+PIPE_HOST=
31+PIPE_SSH_PORT=2222
32+PIPE_WEB_PORT=3000
33+PIPE_PROM_PORT=9222
34+PIPE_DOMAIN=pipe.dev.pico.sh:3001
35+PIPE_PROTOCOL=http
36+PIPE_DEBUG=1
+1,
-1
1@@ -41,7 +41,7 @@ jobs:
2 needs: test
3 strategy:
4 matrix:
5- APP: [prose, pastes, imgs, pgs, feeds, pubsub]
6+ APP: [prose, pastes, imgs, pgs, feeds, pipe]
7 steps:
8 - name: Checkout repo
9 uses: actions/checkout@v3
M
Makefile
+2,
-2
1@@ -58,7 +58,7 @@ bp-%: bp-setup
2 $(DOCKER_BUILDX_BUILD) --build-arg "APP=$*" -t "ghcr.io/picosh/pico/$*-web:$(DOCKER_TAG)" --target release-web .
3 .PHONY: bp-%
4
5-bp-all: bp-prose bp-pastes bp-imgs bp-feeds bp-pgs bp-auth bp-bouncer bp-pubsub
6+bp-all: bp-prose bp-pastes bp-imgs bp-feeds bp-pgs bp-auth bp-bouncer bp-pipe
7 .PHONY: bp-all
8
9 build-auth:
10@@ -74,7 +74,7 @@ build-%:
11 go build -o "build/$*-ssh" "./cmd/$*/ssh"
12 .PHONY: build-%
13
14-build: build-prose build-pastes build-imgs build-feeds build-pgs build-auth build-pico build-pubsub
15+build: build-prose build-pastes build-imgs build-feeds build-pgs build-auth build-pico build-pipe
16 .PHONY: build
17
18 store-clean:
+0,
-13
1@@ -1,9 +1,4 @@
2 {
3- on_demand_tls {
4- ask http://web:3000/check
5- interval 1m
6- burst 10
7- }
8 servers {
9 metrics
10 }
11@@ -129,11 +124,3 @@
12 Access-Control-Allow-Headers "*"
13 }
14 }
15-
16-:443 {
17- reverse_proxy web:3000
18- tls {$APP_EMAIL} {
19- on_demand
20- }
21- encode zstd gzip
22-}
+0,
-102
1@@ -1,102 +0,0 @@
2-{
3- on_demand_tls {
4- ask http://web:3000/check
5- interval 1m
6- burst 10
7- }
8- servers {
9- metrics
10- }
11-}
12-
13-*.{$APP_DOMAIN}, {$APP_DOMAIN} {
14- reverse_proxy web:3000
15- tls {$APP_EMAIL} {
16- dns cloudflare {$CF_API_TOKEN}
17- resolvers 1.1.1.1
18- }
19- encode zstd gzip
20-
21- header {
22- # disable FLoC tracking
23- Permissions-Policy interest-cohort=()
24-
25- # enable HSTS
26- Strict-Transport-Security max-age=31536000;
27-
28- # disable clients from sniffing the media type
29- X-Content-Type-Options nosniff
30-
31- # clickjacking protection
32- X-Frame-Options DENY
33-
34- # keep referrer data off of HTTP connections
35- Referrer-Policy no-referrer-when-downgrade
36-
37- Content-Security-Policy "default-src 'self'; img-src * 'unsafe-inline'; style-src * 'unsafe-inline'"
38-
39- X-XSS-Protection "1; mode=block"
40- }
41-
42- @caddymetrics {
43- host {$APP_DOMAIN}
44- path /_caddy/metrics
45- }
46-
47- metrics @caddymetrics {
48- disable_openmetrics
49- }
50-
51- @appmetrics {
52- host {$APP_DOMAIN}
53- path /_app/metrics
54- }
55-
56- handle @appmetrics {
57- rewrite * /metrics
58- reverse_proxy ssh:9222
59- }
60-}
61-
62-monitoring.{$MONITORING_APP_DOMAIN}, prometheus.{$MONITORING_APP_DOMAIN}, grafana.{$MONITORING_APP_DOMAIN} {
63- @grafana {
64- host grafana.{$MONITORING_APP_DOMAIN}
65- }
66-
67- @prometheus {
68- host prometheus.{$MONITORING_APP_DOMAIN}
69- }
70-
71- tls {$MONITORING_APP_EMAIL} {
72- dns cloudflare {$CF_API_TOKEN}
73- resolvers 1.1.1.1
74- }
75-
76- encode zstd gzip
77-
78- reverse_proxy @grafana grafana:3000
79-
80- basicauth @prometheus {
81- eric JDJhJDE0JDdPOXhoNUdhSmNVNDl6UWpmeTE0cWVkLjRwcUNJUnc0dVQ4MTZNSmVaNjA1TlptaVZYY1hh
82- antonio JDJhJDE0JHI5dkVtMW0vcGxIb011OG4vME5HOU91c3U2VjM2QTZiWVpUeXdSbEg3VUtNZVdhN3BRazFH
83- bot JDJhJDE0JFVsRlNHSDlJbFhDeUd0NldRR2JkcGVFYUJtWGluTHZDVlc5L3QwNWNwWUMuODRlcXZNZHpT
84- }
85- reverse_proxy @prometheus prometheus:9090
86-
87- @caddymetrics {
88- host monitoring.{$MONITORING_APP_DOMAIN}
89- path /_caddy/metrics
90- }
91-
92- metrics @caddymetrics {
93- disable_openmetrics
94- }
95-}
96-
97-:443 {
98- reverse_proxy web:3000
99- tls {$APP_EMAIL} {
100- on_demand
101- }
102- encode zstd gzip
103-}
+1,
-1
1@@ -1,4 +1,4 @@
2-{$APP_DOMAIN}, tmp.pico.sh {
3+{$APP_DOMAIN} {
4 reverse_proxy https://pico-docs-prod.pgs.sh {
5 header_up Host pico-docs-prod.pgs.sh
6 }
+54,
-0
1@@ -0,0 +1,54 @@
2+{
3+ servers {
4+ metrics
5+ }
6+}
7+
8+*.{$APP_DOMAIN}, {$APP_DOMAIN} {
9+ reverse_proxy web:3000
10+ tls {$APP_EMAIL} {
11+ dns cloudflare {$CF_API_TOKEN}
12+ resolvers 1.1.1.1
13+ }
14+ encode zstd gzip
15+
16+ header {
17+ # disable FLoC tracking
18+ Permissions-Policy interest-cohort=()
19+
20+ # enable HSTS
21+ Strict-Transport-Security max-age=31536000;
22+
23+ # disable clients from sniffing the media type
24+ X-Content-Type-Options nosniff
25+
26+ # clickjacking protection
27+ X-Frame-Options DENY
28+
29+ # keep referrer data off of HTTP connections
30+ Referrer-Policy no-referrer-when-downgrade
31+
32+ Content-Security-Policy "default-src 'self'; img-src * 'unsafe-inline'; style-src * 'unsafe-inline'"
33+
34+ X-XSS-Protection "1; mode=block"
35+ }
36+
37+ @caddymetrics {
38+ host {$APP_DOMAIN}
39+ path /_caddy/metrics
40+ }
41+
42+ metrics @caddymetrics {
43+ disable_openmetrics
44+ }
45+
46+ @appmetrics {
47+ host {$APP_DOMAIN}
48+ path /_app/metrics
49+ }
50+
51+ handle @appmetrics {
52+ rewrite * /metrics
53+ reverse_proxy ssh:9222
54+ }
55+}
+0,
-8
1@@ -1,8 +0,0 @@
2-{$APP_DOMAIN} {
3- reverse_proxy web:3000
4-
5- tls {$APP_EMAIL} {
6- dns cloudflare {$CF_API_TOKEN}
7- resolvers 1.1.1.1
8- }
9-}
+7,
-0
1@@ -0,0 +1,7 @@
2+package main
3+
4+import "github.com/picosh/pico/pipe"
5+
6+func main() {
7+ pipe.StartSshServer()
8+}
+7,
-0
1@@ -0,0 +1,7 @@
2+package main
3+
4+import "github.com/picosh/pico/pipe"
5+
6+func main() {
7+ pipe.StartApiServer()
8+}
+0,
-7
1@@ -1,7 +0,0 @@
2-package main
3-
4-import "github.com/picosh/pico/pubsub"
5-
6-func main() {
7- pubsub.StartSshServer()
8-}
+0,
-7
1@@ -1,7 +0,0 @@
2-package main
3-
4-import "github.com/picosh/pico/pubsub"
5-
6-func main() {
7- pubsub.StartApiServer()
8-}
+5,
-5
1@@ -45,24 +45,24 @@ services:
2 - ./data/pastes-ssh/data:/app/ssh_data
3 ports:
4 - "2221:2222"
5- pubsub-web:
6+ pipe-web:
7 build:
8 args:
9- APP: pubsub
10+ APP: pipe
11 target: release-web
12 env_file:
13 - .env.example
14 ports:
15 - "3001:3000"
16- pubsub-ssh:
17+ pipe-ssh:
18 build:
19 args:
20- APP: pubsub
21+ APP: pipe
22 target: release-ssh
23 env_file:
24 - .env.example
25 volumes:
26- - ./data/pubsub-ssh/data:/app/ssh_data
27+ - ./data/pipe-ssh/data:/app/ssh_data
28 ports:
29 - "2221:2222"
30 prose-web:
+22,
-22
1@@ -88,50 +88,50 @@ services:
2 ports:
3 - "${PASTES_SSH_V4:-22}:2222"
4 - "${PASTES_SSH_V6:-[::1]:22}:2222"
5- pubsub-caddy:
6+ pipe-caddy:
7 image: ghcr.io/picosh/pico/caddy:latest
8 restart: always
9 networks:
10- - pubsub
11+ - pipe
12 env_file:
13 - .env.prod
14 environment:
15- APP_DOMAIN: ${PUBSUB_DOMAIN:-pipe.pico.sh}
16- APP_EMAIL: ${PUBSUB_EMAIL:-hello@pico.sh}
17+ APP_DOMAIN: ${PIPE_DOMAIN:-pipe.pico.sh}
18+ APP_EMAIL: ${PIPE_EMAIL:-hello@pico.sh}
19 volumes:
20- - ${PUBSUB_CADDYFILE}:/etc/caddy/Caddyfile
21- - ./data/pubsub-caddy/data:/data
22- - ./data/pubsub-caddy/config:/config
23+ - ${PIPE_CADDYFILE}:/etc/caddy/Caddyfile
24+ - ./data/pipe-caddy/data:/data
25+ - ./data/pipe-caddy/config:/config
26 ports:
27- - "${PUBSUB_HTTPS_V4:-443}:443"
28- - "${PUBSUB_HTTP_V4:-80}:80"
29- - "${PUBSUB_HTTPS_V6:-[::1]:443}:443"
30- - "${PUBSUB_HTTP_V6:-[::1]:80}:80"
31+ - "${PIPE_HTTPS_V4:-443}:443"
32+ - "${PIPE_HTTP_V4:-80}:80"
33+ - "${PIPE_HTTPS_V6:-[::1]:443}:443"
34+ - "${PIPE_HTTP_V6:-[::1]:80}:80"
35 profiles:
36- - pubsub
37+ - pipe
38 - caddy
39 - all
40- pubsub-web:
41+ pipe-web:
42 networks:
43- pubsub:
44+ pipe:
45 aliases:
46 - web
47 env_file:
48 - .env.prod
49 volumes:
50- - ./data/pubsub-ssh/data:/app/ssh_data
51- pubsub-ssh:
52+ - ./data/pipe-ssh/data:/app/ssh_data
53+ pipe-ssh:
54 networks:
55- pubsub:
56+ pipe:
57 aliases:
58 - ssh
59 env_file:
60 - .env.prod
61 volumes:
62- - ./data/pubsub-ssh/data:/app/ssh_data
63+ - ./data/pipe-ssh/data:/app/ssh_data
64 ports:
65- - "${PUBSUB_SSH_V4:-22}:2222"
66- - "${PUBSUB_SSH_V6:-[::1]:22}:2222"
67+ - "${PIPE_SSH_V4:-22}:2222"
68+ - "${PIPE_SSH_V6:-[::1]:22}:2222"
69 prose-caddy:
70 image: ghcr.io/picosh/pico/caddy:latest
71 restart: always
72@@ -396,9 +396,9 @@ networks:
73 ipam:
74 config:
75 - subnet: 172.25.0.0/16
76- pubsub:
77+ pipe:
78 driver_opts:
79- com.docker.network.bridge.name: pubsub
80+ com.docker.network.bridge.name: pipe
81 ipam:
82 config:
83 - subnet: 172.27.0.0/16
+6,
-6
1@@ -43,18 +43,18 @@ services:
2 - pastes
3 - services
4 - all
5- pubsub-web:
6- image: ghcr.io/picosh/pico/pubsub-web:latest
7+ pipe-web:
8+ image: ghcr.io/picosh/pico/pipe-web:latest
9 restart: always
10 profiles:
11- - pubsub
12+ - pipe
13 - services
14 - all
15- pubsub-ssh:
16- image: ghcr.io/picosh/pico/pubsub-ssh:latest
17+ pipe-ssh:
18+ image: ghcr.io/picosh/pico/pipe-ssh:latest
19 restart: always
20 profiles:
21- - pubsub
22+ - pipe
23 - services
24 - all
25 prose-web:
+2,
-2
1@@ -13,7 +13,7 @@ import (
2 "github.com/charmbracelet/wish"
3 "github.com/picosh/pico/db/postgres"
4 "github.com/picosh/pico/filehandlers"
5- "github.com/picosh/pico/filehandlers/util"
6+ "github.com/picosh/pico/shared"
7 "github.com/picosh/pico/shared/storage"
8 wsh "github.com/picosh/pico/wish"
9 "github.com/picosh/send/auth"
10@@ -83,7 +83,7 @@ func StartSshServer() {
11 }
12 handler := filehandlers.NewFileHandlerRouter(cfg, dbh, fileMap)
13
14- sshAuth := util.NewSshAuthHandler(dbh, logger, cfg)
15+ sshAuth := shared.NewSshAuthHandler(dbh, logger, cfg)
16 s, err := wish.NewServer(
17 wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
18 wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
+6,
-8
1@@ -16,8 +16,6 @@ import (
2 "github.com/charmbracelet/ssh"
3 "github.com/charmbracelet/wish"
4 "github.com/picosh/pico/db"
5- "github.com/picosh/pico/filehandlers/util"
6- futil "github.com/picosh/pico/filehandlers/util"
7 "github.com/picosh/pico/shared"
8 "github.com/picosh/pico/shared/storage"
9 "github.com/picosh/pobj"
10@@ -118,7 +116,7 @@ func (h *UploadAssetHandler) GetLogger() *slog.Logger {
11 }
12
13 func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
14- user, err := futil.GetUser(s.Context())
15+ user, err := shared.GetUser(s.Context())
16 if err != nil {
17 return nil, nil, err
18 }
19@@ -152,7 +150,7 @@ func (h *UploadAssetHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os
20 func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
21 var fileList []os.FileInfo
22
23- user, err := futil.GetUser(s.Context())
24+ user, err := shared.GetUser(s.Context())
25 if err != nil {
26 return fileList, err
27 }
28@@ -194,7 +192,7 @@ func (h *UploadAssetHandler) List(s ssh.Session, fpath string, isDir bool, recur
29 }
30
31 func (h *UploadAssetHandler) Validate(s ssh.Session) error {
32- user, err := util.GetUser(s.Context())
33+ user, err := shared.GetUser(s.Context())
34 if err != nil {
35 return err
36 }
37@@ -245,7 +243,7 @@ func (h *UploadAssetHandler) findDenylist(bucket sst.Bucket, project *db.Project
38 }
39
40 func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
41- user, err := futil.GetUser(s.Context())
42+ user, err := shared.GetUser(s.Context())
43 if err != nil {
44 h.Cfg.Logger.Error("user not found in ctx", "err", err.Error())
45 return "", err
46@@ -311,7 +309,7 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (s
47 return "", err
48 }
49
50- featureFlag, err := futil.GetFeatureFlag(s.Context())
51+ featureFlag, err := shared.GetFeatureFlag(s.Context())
52 if err != nil {
53 return "", err
54 }
55@@ -403,7 +401,7 @@ func (h *UploadAssetHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (s
56 }
57
58 func (h *UploadAssetHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
59- user, err := futil.GetUser(s.Context())
60+ user, err := shared.GetUser(s.Context())
61 if err != nil {
62 h.Cfg.Logger.Error("user not found in ctx", "err", err.Error())
63 return err
+4,
-5
1@@ -14,7 +14,6 @@ import (
2 "github.com/charmbracelet/ssh"
3 exifremove "github.com/neurosnap/go-exif-remove"
4 "github.com/picosh/pico/db"
5- "github.com/picosh/pico/filehandlers/util"
6 "github.com/picosh/pico/shared"
7 "github.com/picosh/pico/shared/storage"
8 "github.com/picosh/pobj"
9@@ -49,7 +48,7 @@ func NewUploadImgHandler(dbpool db.DB, cfg *shared.ConfigSite, storage storage.S
10 }
11
12 func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
13- user, err := util.GetUser(s.Context())
14+ user, err := shared.GetUser(s.Context())
15 if err != nil {
16 return nil, nil, err
17 }
18@@ -89,7 +88,7 @@ func (h *UploadImgHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.F
19
20 func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
21 logger := h.Cfg.Logger
22- user, err := util.GetUser(s.Context())
23+ user, err := shared.GetUser(s.Context())
24 if err != nil {
25 logger.Error("could not get user from ctx", "err", err.Error())
26 return "", err
27@@ -146,7 +145,7 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
28 logger.Info("unable to find image, continuing", "filename", nextPost.Filename, "err", err.Error())
29 }
30
31- featureFlag, err := util.GetFeatureFlag(s.Context())
32+ featureFlag, err := shared.GetFeatureFlag(s.Context())
33 if err != nil {
34 return "", err
35 }
36@@ -193,7 +192,7 @@ func (h *UploadImgHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
37 }
38
39 func (h *UploadImgHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
40- user, err := util.GetUser(s.Context())
41+ user, err := shared.GetUser(s.Context())
42 if err != nil {
43 return err
44 }
+1,
-2
1@@ -8,7 +8,6 @@ import (
2
3 "github.com/charmbracelet/ssh"
4 "github.com/picosh/pico/db"
5- "github.com/picosh/pico/filehandlers/util"
6 "github.com/picosh/pico/shared"
7 sendutils "github.com/picosh/send/utils"
8 "github.com/picosh/utils"
9@@ -81,7 +80,7 @@ func (h *UploadImgHandler) writeImg(s ssh.Session, data *PostMetaData) error {
10 if !valid {
11 return err
12 }
13- user, err := util.GetUser(s.Context())
14+ user, err := shared.GetUser(s.Context())
15 if err != nil {
16 return err
17 }
+3,
-4
1@@ -12,7 +12,6 @@ import (
2
3 "github.com/charmbracelet/ssh"
4 "github.com/picosh/pico/db"
5- "github.com/picosh/pico/filehandlers/util"
6 "github.com/picosh/pico/shared"
7 "github.com/picosh/pico/shared/storage"
8 sendutils "github.com/picosh/send/utils"
9@@ -48,7 +47,7 @@ func NewScpPostHandler(dbpool db.DB, cfg *shared.ConfigSite, hooks ScpFileHooks,
10 }
11
12 func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
13- user, err := util.GetUser(s.Context())
14+ user, err := shared.GetUser(s.Context())
15 if err != nil {
16 return nil, nil, err
17 }
18@@ -77,7 +76,7 @@ func (h *ScpUploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.F
19
20 func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
21 logger := h.Cfg.Logger
22- user, err := util.GetUser(s.Context())
23+ user, err := shared.GetUser(s.Context())
24 if err != nil {
25 logger.Error("error getting user from ctx", "err", err.Error())
26 return "", err
27@@ -264,7 +263,7 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (str
28
29 func (h *ScpUploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error {
30 logger := h.Cfg.Logger
31- user, err := util.GetUser(s.Context())
32+ user, err := shared.GetUser(s.Context())
33 if err != nil {
34 logger.Error("could not get user from ctx", "err", err.Error())
35 return err
+2,
-3
1@@ -10,7 +10,6 @@ import (
2
3 "github.com/charmbracelet/ssh"
4 "github.com/picosh/pico/db"
5- "github.com/picosh/pico/filehandlers/util"
6 "github.com/picosh/pico/shared"
7 "github.com/picosh/send/utils"
8 )
9@@ -83,7 +82,7 @@ func (r *FileHandlerRouter) Read(s ssh.Session, entry *utils.FileEntry) (os.File
10
11 func BaseList(s ssh.Session, fpath string, isDir bool, recursive bool, spaces []string, dbpool db.DB) ([]os.FileInfo, error) {
12 var fileList []os.FileInfo
13- user, err := util.GetUser(s.Context())
14+ user, err := shared.GetUser(s.Context())
15 if err != nil {
16 return fileList, err
17 }
18@@ -154,7 +153,7 @@ func (r *FileHandlerRouter) GetLogger() *slog.Logger {
19 }
20
21 func (r *FileHandlerRouter) Validate(s ssh.Session) error {
22- user, err := util.GetUser(s.Context())
23+ user, err := shared.GetUser(s.Context())
24 if err != nil {
25 return err
26 }
+0,
-64
1@@ -1,64 +0,0 @@
2-package util
3-
4-import (
5- "log/slog"
6-
7- "github.com/charmbracelet/ssh"
8- "github.com/picosh/pico/db"
9- "github.com/picosh/pico/shared"
10- "github.com/picosh/utils"
11-)
12-
13-type SshAuthHandler struct {
14- DBPool db.DB
15- Logger *slog.Logger
16- Cfg *shared.ConfigSite
17-}
18-
19-func NewSshAuthHandler(dbpool db.DB, logger *slog.Logger, cfg *shared.ConfigSite) *SshAuthHandler {
20- return &SshAuthHandler{
21- DBPool: dbpool,
22- Logger: logger,
23- Cfg: cfg,
24- }
25-}
26-
27-func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool {
28- shared.SetPublicKeyCtx(ctx, key)
29-
30- pubkey := utils.KeyForKeyText(key)
31-
32- user, err := r.DBPool.FindUserForKey(ctx.User(), pubkey)
33- if err != nil {
34- r.Logger.Error(
35- "could not find user for key",
36- "key", key,
37- "err", err,
38- )
39- return false
40- }
41-
42- if user.Name == "" {
43- r.Logger.Error("username is not set")
44- return false
45- }
46-
47- ff, _ := r.DBPool.FindFeatureForUser(user.ID, "plus")
48- // we have free tiers so users might not have a feature flag
49- // in which case we set sane defaults
50- if ff == nil {
51- ff = db.NewFeatureFlag(
52- user.ID,
53- "plus",
54- r.Cfg.MaxSize,
55- r.Cfg.MaxAssetSize,
56- )
57- }
58- // this is jank
59- ff.Data.StorageMax = ff.FindStorageMax(r.Cfg.MaxSize)
60- ff.Data.FileMax = ff.FindFileMax(r.Cfg.MaxAssetSize)
61-
62- SetUser(ctx, user)
63- SetFeatureFlag(ctx, ff)
64- return true
65-}
+0,
-35
1@@ -1,35 +0,0 @@
2-package util
3-
4-import (
5- "fmt"
6-
7- "github.com/charmbracelet/ssh"
8- "github.com/picosh/pico/db"
9-)
10-
11-type ctxUserKey struct{}
12-type ctxFeatureFlagKey struct{}
13-
14-func GetUser(ctx ssh.Context) (*db.User, error) {
15- user, ok := ctx.Value(ctxUserKey{}).(*db.User)
16- if !ok {
17- return user, fmt.Errorf("user not set on `ssh.Context()` for connection")
18- }
19- return user, nil
20-}
21-
22-func SetUser(ctx ssh.Context, user *db.User) {
23- ctx.SetValue(ctxUserKey{}, user)
24-}
25-
26-func GetFeatureFlag(ctx ssh.Context) (*db.FeatureFlag, error) {
27- ff, ok := ctx.Value(ctxFeatureFlagKey{}).(*db.FeatureFlag)
28- if !ok || ff.Name == "" {
29- return ff, fmt.Errorf("feature flag not set on `ssh.Context()` for connection")
30- }
31- return ff, nil
32-}
33-
34-func SetFeatureFlag(ctx ssh.Context, ff *db.FeatureFlag) {
35- ctx.SetValue(ctxFeatureFlagKey{}, ff)
36-}
+2,
-2
1@@ -13,7 +13,7 @@ import (
2 "github.com/charmbracelet/wish"
3 "github.com/picosh/pico/db/postgres"
4 "github.com/picosh/pico/filehandlers"
5- "github.com/picosh/pico/filehandlers/util"
6+ "github.com/picosh/pico/shared"
7 "github.com/picosh/pico/shared/storage"
8 wsh "github.com/picosh/pico/wish"
9 "github.com/picosh/send/auth"
10@@ -81,7 +81,7 @@ func StartSshServer() {
11 "fallback": filehandlers.NewScpPostHandler(dbh, cfg, hooks, st),
12 }
13 handler := filehandlers.NewFileHandlerRouter(cfg, dbh, fileMap)
14- sshAuth := util.NewSshAuthHandler(dbh, logger, cfg)
15+ sshAuth := shared.NewSshAuthHandler(dbh, logger, cfg)
16 s, err := wish.NewServer(
17 wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
18 wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
+1,
-2
1@@ -14,7 +14,6 @@ import (
2 "github.com/picosh/pico/db"
3 "github.com/picosh/pico/db/postgres"
4 uploadassets "github.com/picosh/pico/filehandlers/assets"
5- "github.com/picosh/pico/filehandlers/util"
6 "github.com/picosh/pico/shared"
7 "github.com/picosh/pico/shared/storage"
8 wsh "github.com/picosh/pico/wish"
9@@ -97,7 +96,7 @@ func StartSshServer() {
10 HttpHandler: createHttpHandler(apiConfig),
11 }
12
13- sshAuth := util.NewSshAuthHandler(dbpool, logger, cfg)
14+ sshAuth := shared.NewSshAuthHandler(dbpool, logger, cfg)
15 s, err := wish.NewServer(
16 wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
17 wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
+3,
-3
1@@ -38,7 +38,7 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge {
2 "impersonating", asUser,
3 )
4
5- pubkey, err := shared.GetPublicKeyCtx(ctx)
6+ pubkey, err := shared.GetPublicKey(ctx)
7 if err != nil {
8 log.Error(err.Error(), "subdomain", subdomain)
9 return http.HandlerFunc(shared.UnauthorizedHandler)
10@@ -88,7 +88,7 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge {
11 requester, _ = dbh.FindUserForName(asUser)
12 }
13
14- shared.SetUserCtx(ctx, requester)
15+ shared.SetUser(ctx, requester)
16
17 if !HasProjectAccess(project, owner, requester, pubkey) {
18 log.Error("no access")
19@@ -101,7 +101,7 @@ func createHttpHandler(apiConfig *shared.ApiConfig) CtxHttpBridge {
20 // special API endpoint for tunnel users accessing site
21 shared.NewCorsRoute("GET", "/api/current_user", func(w http.ResponseWriter, r *http.Request) {
22 w.Header().Set("Content-Type", "application/json")
23- user, err := shared.GetUserCtx(ctx)
24+ user, err := shared.GetUser(ctx)
25 if err != nil {
26 logger.Error("could not find user", "err", err.Error())
27 shared.JSONError(w, err.Error(), http.StatusNotFound)
+4,
-5
1@@ -14,7 +14,6 @@ import (
2 "github.com/charmbracelet/ssh"
3 "github.com/charmbracelet/wish"
4 "github.com/picosh/pico/db"
5- "github.com/picosh/pico/filehandlers/util"
6 "github.com/picosh/pico/shared"
7 sendutils "github.com/picosh/send/utils"
8 "github.com/picosh/utils"
9@@ -57,7 +56,7 @@ func (h *UploadHandler) Delete(s ssh.Session, entry *sendutils.FileEntry) error
10 }
11
12 func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.FileInfo, sendutils.ReaderAtCloser, error) {
13- user, err := util.GetUser(s.Context())
14+ user, err := shared.GetUser(s.Context())
15 if err != nil {
16 return nil, nil, err
17 }
18@@ -81,7 +80,7 @@ func (h *UploadHandler) Read(s ssh.Session, entry *sendutils.FileEntry) (os.File
19
20 func (h *UploadHandler) List(s ssh.Session, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
21 var fileList []os.FileInfo
22- user, err := util.GetUser(s.Context())
23+ user, err := shared.GetUser(s.Context())
24 if err != nil {
25 return fileList, err
26 }
27@@ -136,7 +135,7 @@ func (h *UploadHandler) Validate(s ssh.Session) error {
28 return fmt.Errorf("must have username set")
29 }
30
31- util.SetUser(s.Context(), user)
32+ shared.SetUser(s.Context(), user)
33 return nil
34 }
35
36@@ -277,7 +276,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger,
37
38 func (h *UploadHandler) Write(s ssh.Session, entry *sendutils.FileEntry) (string, error) {
39 logger := h.Cfg.Logger
40- user, err := util.GetUser(s.Context())
41+ user, err := shared.GetUser(s.Context())
42 if err != nil {
43 logger.Error(err.Error())
44 return "", err
+1,
-1
1@@ -28,7 +28,7 @@ import (
2 )
3
4 func authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
5- shared.SetPublicKeyCtx(ctx, key)
6+ shared.SetPublicKey(ctx, key)
7 return true
8 }
9
R pubsub/api.go =>
pipe/api.go
+1,
-1
1@@ -1,4 +1,4 @@
2-package pubsub
3+package pipe
4
5 import (
6 "fmt"
R pubsub/cli.go =>
pipe/cli.go
+1,
-1
1@@ -1,4 +1,4 @@
2-package pubsub
3+package pipe
4
5 import (
6 "bytes"
R pubsub/config.go =>
pipe/config.go
+6,
-6
1@@ -1,4 +1,4 @@
2-package pubsub
3+package pipe
4
5 import (
6 "github.com/picosh/pico/shared"
7@@ -6,17 +6,17 @@ import (
8 )
9
10 func NewConfigSite() *shared.ConfigSite {
11- domain := utils.GetEnv("PUBSUB_DOMAIN", "pipe.pico.sh")
12- port := utils.GetEnv("PUBSUB_WEB_PORT", "3000")
13+ domain := utils.GetEnv("PIPE_DOMAIN", "pipe.pico.sh")
14+ port := utils.GetEnv("PIPE_WEB_PORT", "3000")
15 dbURL := utils.GetEnv("DATABASE_URL", "")
16- protocol := utils.GetEnv("PUBSUB_PROTOCOL", "https")
17+ protocol := utils.GetEnv("PIPE_PROTOCOL", "https")
18
19 return &shared.ConfigSite{
20 Domain: domain,
21 Port: port,
22 Protocol: protocol,
23 DbURL: dbURL,
24- Logger: shared.CreateLogger("pubsub"),
25- Space: "pubsub",
26+ Logger: shared.CreateLogger("pipe"),
27+ Space: "pipe",
28 }
29 }
R pubsub/html/base.layout.tmpl =>
pipe/html/base.layout.tmpl
+0,
-0
R pubsub/html/marketing.page.tmpl =>
pipe/html/marketing.page.tmpl
+0,
-0
R pubsub/public/anim.js =>
pipe/public/anim.js
+0,
-0
R pubsub/public/apple-touch-icon.png =>
pipe/public/apple-touch-icon.png
+0,
-0
R pubsub/public/favicon-16x16.png =>
pipe/public/favicon-16x16.png
+0,
-0
R pubsub/public/favicon.ico =>
pipe/public/favicon.ico
+0,
-0
R pubsub/public/robots.txt =>
pipe/public/robots.txt
+0,
-0
R pubsub/ssh.go =>
pipe/ssh.go
+8,
-8
1@@ -1,4 +1,4 @@
2-package pubsub
3+package pipe
4
5 import (
6 "context"
7@@ -12,17 +12,17 @@ import (
8 "github.com/charmbracelet/promwish"
9 "github.com/charmbracelet/wish"
10 "github.com/picosh/pico/db/postgres"
11- "github.com/picosh/pico/filehandlers/util"
12+ "github.com/picosh/pico/shared"
13 wsh "github.com/picosh/pico/wish"
14 psub "github.com/picosh/pubsub"
15 "github.com/picosh/utils"
16 )
17
18 func StartSshServer() {
19- host := utils.GetEnv("PUBSUB_HOST", "0.0.0.0")
20- port := utils.GetEnv("PUBSUB_SSH_PORT", "2222")
21- portOverride := utils.GetEnv("PUBSUB_SSH_PORT_OVERRIDE", port)
22- promPort := utils.GetEnv("PUBSUB_PROM_PORT", "9222")
23+ host := utils.GetEnv("PIPE_HOST", "0.0.0.0")
24+ port := utils.GetEnv("PIPE_SSH_PORT", "2222")
25+ portOverride := utils.GetEnv("PIPE_SSH_PORT_OVERRIDE", port)
26+ promPort := utils.GetEnv("PIPE_PROM_PORT", "9222")
27 cfg := NewConfigSite()
28 logger := cfg.Logger
29 dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
30@@ -40,14 +40,14 @@ func StartSshServer() {
31 Waiters: syncmap.New[string, []string](),
32 }
33
34- sshAuth := util.NewSshAuthHandler(dbh, logger, cfg)
35+ sshAuth := shared.NewSshAuthHandler(dbh, logger, cfg)
36 s, err := wish.NewServer(
37 wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
38 wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
39 wish.WithPublicKeyAuth(sshAuth.PubkeyAuthHandler),
40 wish.WithMiddleware(
41 WishMiddleware(handler),
42- promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "pubsub-ssh"),
43+ promwish.Middleware(fmt.Sprintf("%s:%s", host, promPort), "pipe-ssh"),
44 wsh.LogMiddleware(logger),
45 ),
46 )
+2,
-2
1@@ -14,7 +14,7 @@ import (
2 "github.com/picosh/pico/db/postgres"
3 "github.com/picosh/pico/filehandlers"
4 uploadimgs "github.com/picosh/pico/filehandlers/imgs"
5- "github.com/picosh/pico/filehandlers/util"
6+ "github.com/picosh/pico/shared"
7 "github.com/picosh/pico/shared/storage"
8 wsh "github.com/picosh/pico/wish"
9 "github.com/picosh/send/auth"
10@@ -92,7 +92,7 @@ func StartSshServer() {
11 DBPool: dbh,
12 }
13
14- sshAuth := util.NewSshAuthHandler(dbh, logger, cfg)
15+ sshAuth := shared.NewSshAuthHandler(dbh, logger, cfg)
16 s, err := wish.NewServer(
17 wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
18 wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
1@@ -1,7 +1,105 @@
2 package shared
3
4-import "github.com/charmbracelet/ssh"
5+import (
6+ "fmt"
7+ "log/slog"
8
9-func PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool {
10+ "github.com/charmbracelet/ssh"
11+ "github.com/picosh/pico/db"
12+ "github.com/picosh/utils"
13+)
14+
15+type ctxUserKey struct{}
16+type ctxFeatureFlagKey struct{}
17+
18+func GetUser(ctx ssh.Context) (*db.User, error) {
19+ user, ok := ctx.Value(ctxUserKey{}).(*db.User)
20+ if !ok {
21+ return user, fmt.Errorf("user not set on `ssh.Context()` for connection")
22+ }
23+ return user, nil
24+}
25+
26+func SetUser(ctx ssh.Context, user *db.User) {
27+ ctx.SetValue(ctxUserKey{}, user)
28+}
29+
30+func GetFeatureFlag(ctx ssh.Context) (*db.FeatureFlag, error) {
31+ ff, ok := ctx.Value(ctxFeatureFlagKey{}).(*db.FeatureFlag)
32+ if !ok || ff.Name == "" {
33+ return ff, fmt.Errorf("feature flag not set on `ssh.Context()` for connection")
34+ }
35+ return ff, nil
36+}
37+
38+func SetFeatureFlag(ctx ssh.Context, ff *db.FeatureFlag) {
39+ ctx.SetValue(ctxFeatureFlagKey{}, ff)
40+}
41+
42+type ctxPublicKey struct{}
43+
44+func GetPublicKey(ctx ssh.Context) (ssh.PublicKey, error) {
45+ pk, ok := ctx.Value(ctxPublicKey{}).(ssh.PublicKey)
46+ if !ok {
47+ return nil, fmt.Errorf("public key not set on `ssh.Context()` for connection")
48+ }
49+ return pk, nil
50+}
51+
52+func SetPublicKey(ctx ssh.Context, pk ssh.PublicKey) {
53+ ctx.SetValue(ctxPublicKey{}, pk)
54+}
55+
56+type SshAuthHandler struct {
57+ DBPool db.DB
58+ Logger *slog.Logger
59+ Cfg *ConfigSite
60+}
61+
62+func NewSshAuthHandler(dbpool db.DB, logger *slog.Logger, cfg *ConfigSite) *SshAuthHandler {
63+ return &SshAuthHandler{
64+ DBPool: dbpool,
65+ Logger: logger,
66+ Cfg: cfg,
67+ }
68+}
69+
70+func (r *SshAuthHandler) PubkeyAuthHandler(ctx ssh.Context, key ssh.PublicKey) bool {
71+ SetPublicKey(ctx, key)
72+
73+ pubkey := utils.KeyForKeyText(key)
74+
75+ user, err := r.DBPool.FindUserForKey(ctx.User(), pubkey)
76+ if err != nil {
77+ r.Logger.Error(
78+ "could not find user for key",
79+ "key", key,
80+ "err", err,
81+ )
82+ return false
83+ }
84+
85+ if user.Name == "" {
86+ r.Logger.Error("username is not set")
87+ return false
88+ }
89+
90+ ff, _ := r.DBPool.FindFeatureForUser(user.ID, "plus")
91+ // we have free tiers so users might not have a feature flag
92+ // in which case we set sane defaults
93+ if ff == nil {
94+ ff = db.NewFeatureFlag(
95+ user.ID,
96+ "plus",
97+ r.Cfg.MaxSize,
98+ r.Cfg.MaxAssetSize,
99+ )
100+ }
101+ // this is jank
102+ ff.Data.StorageMax = ff.FindStorageMax(r.Cfg.MaxSize)
103+ ff.Data.FileMax = ff.FindFileMax(r.Cfg.MaxAssetSize)
104+
105+ SetUser(ctx, user)
106+ SetFeatureFlag(ctx, ff)
107 return true
108 }
1@@ -1,35 +1 @@
2 package shared
3-
4-import (
5- "fmt"
6-
7- "github.com/charmbracelet/ssh"
8- "github.com/picosh/pico/db"
9-)
10-
11-type ctxPublicKey struct{}
12-type ctxUserKey struct{}
13-
14-func GetPublicKeyCtx(ctx ssh.Context) (ssh.PublicKey, error) {
15- pk, ok := ctx.Value(ctxPublicKey{}).(ssh.PublicKey)
16- if !ok {
17- return nil, fmt.Errorf("public key not set on `ssh.Context()` for connection")
18- }
19- return pk, nil
20-}
21-
22-func SetPublicKeyCtx(ctx ssh.Context, pk ssh.PublicKey) {
23- ctx.SetValue(ctxPublicKey{}, pk)
24-}
25-
26-func GetUserCtx(ctx ssh.Context) (*db.User, error) {
27- pk, ok := ctx.Value(ctxUserKey{}).(*db.User)
28- if !ok {
29- return nil, fmt.Errorf("user not set on `ssh.Context()` for connection")
30- }
31- return pk, nil
32-}
33-
34-func SetUserCtx(ctx ssh.Context, user *db.User) {
35- ctx.SetValue(ctxUserKey{}, user)
36-}
+17,
-17
1@@ -47,7 +47,7 @@ func registerUser(apiConfig *shared.ApiConfig, ctx ssh.Context, pubkey ssh.Publi
2 }
3
4 picoApi := shared.NewUserApi(user, pubkey)
5- shared.SetUserCtx(ctx, user)
6+ shared.SetUser(ctx, user)
7 err = json.NewEncoder(w).Encode(picoApi)
8 if err != nil {
9 logger.Error("json encoding error", "err", err.Error())
10@@ -63,7 +63,7 @@ func getFeatures(apiConfig *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc
11 logger := apiConfig.Cfg.Logger
12 return func(w http.ResponseWriter, r *http.Request) {
13 w.Header().Set("Content-Type", "application/json")
14- user, _ := shared.GetUserCtx(ctx)
15+ user, _ := shared.GetUser(ctx)
16 if !ensureUser(w, user) {
17 return
18 }
19@@ -93,7 +93,7 @@ func findOrCreateRssToken(apiConfig *shared.ApiConfig, ctx ssh.Context) http.Han
20 logger := apiConfig.Cfg.Logger
21 return func(w http.ResponseWriter, r *http.Request) {
22 w.Header().Set("Content-Type", "application/json")
23- user, _ := shared.GetUserCtx(ctx)
24+ user, _ := shared.GetUser(ctx)
25 if !ensureUser(w, user) {
26 return
27 }
28@@ -132,7 +132,7 @@ func getPublicKeys(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc
29 logger := httpCtx.Cfg.Logger
30 return func(w http.ResponseWriter, r *http.Request) {
31 w.Header().Set("Content-Type", "application/json")
32- user, _ := shared.GetUserCtx(ctx)
33+ user, _ := shared.GetUser(ctx)
34 if !ensureUser(w, user) {
35 return
36 }
37@@ -169,7 +169,7 @@ func createPubkey(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
38 logger := httpCtx.Cfg.Logger
39 return func(w http.ResponseWriter, r *http.Request) {
40 w.Header().Set("Content-Type", "application/json")
41- user, _ := shared.GetUserCtx(ctx)
42+ user, _ := shared.GetUser(ctx)
43 if !ensureUser(w, user) {
44 return
45 }
46@@ -207,7 +207,7 @@ func deletePubkey(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
47 logger := httpCtx.Cfg.Logger
48 return func(w http.ResponseWriter, r *http.Request) {
49 w.Header().Set("Content-Type", "application/json")
50- user, _ := shared.GetUserCtx(ctx)
51+ user, _ := shared.GetUser(ctx)
52 if !ensureUser(w, user) {
53 return
54 }
55@@ -249,7 +249,7 @@ func patchPubkey(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
56 logger := httpCtx.Cfg.Logger
57 return func(w http.ResponseWriter, r *http.Request) {
58 w.Header().Set("Content-Type", "application/json")
59- user, _ := shared.GetUserCtx(ctx)
60+ user, _ := shared.GetUser(ctx)
61 if !ensureUser(w, user) {
62 return
63 }
64@@ -303,7 +303,7 @@ func getTokens(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
65 logger := httpCtx.Cfg.Logger
66 return func(w http.ResponseWriter, r *http.Request) {
67 w.Header().Set("Content-Type", "application/json")
68- user, _ := shared.GetUserCtx(ctx)
69+ user, _ := shared.GetUser(ctx)
70 if !ensureUser(w, user) {
71 return
72 }
73@@ -339,7 +339,7 @@ func createToken(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
74 logger := httpCtx.Cfg.Logger
75 return func(w http.ResponseWriter, r *http.Request) {
76 w.Header().Set("Content-Type", "application/json")
77- user, _ := shared.GetUserCtx(ctx)
78+ user, _ := shared.GetUser(ctx)
79 if !ensureUser(w, user) {
80 return
81 }
82@@ -379,7 +379,7 @@ func deleteToken(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
83 logger := httpCtx.Cfg.Logger
84 return func(w http.ResponseWriter, r *http.Request) {
85 w.Header().Set("Content-Type", "application/json")
86- user, _ := shared.GetUserCtx(ctx)
87+ user, _ := shared.GetUser(ctx)
88 if !ensureUser(w, user) {
89 return
90 }
91@@ -425,7 +425,7 @@ func getProjects(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
92 logger := httpCtx.Cfg.Logger
93 return func(w http.ResponseWriter, r *http.Request) {
94 w.Header().Set("Content-Type", "application/json")
95- user, _ := shared.GetUserCtx(ctx)
96+ user, _ := shared.GetUser(ctx)
97 if !ensureUser(w, user) {
98 return
99 }
100@@ -456,7 +456,7 @@ func getPosts(httpCtx *shared.ApiConfig, ctx ssh.Context, space string) http.Han
101 logger := httpCtx.Cfg.Logger
102 return func(w http.ResponseWriter, r *http.Request) {
103 w.Header().Set("Content-Type", "application/json")
104- user, _ := shared.GetUserCtx(ctx)
105+ user, _ := shared.GetUser(ctx)
106 if !ensureUser(w, user) {
107 return
108 }
109@@ -502,7 +502,7 @@ func createFeature(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc
110 logger := httpCtx.Cfg.Logger
111 return func(w http.ResponseWriter, r *http.Request) {
112 w.Header().Set("Content-Type", "application/json")
113- user, _ := shared.GetUserCtx(ctx)
114+ user, _ := shared.GetUser(ctx)
115 if !ensureUser(w, user) {
116 return
117 }
118@@ -542,7 +542,7 @@ func deleteFeature(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc
119 logger := httpCtx.Cfg.Logger
120 return func(w http.ResponseWriter, r *http.Request) {
121 w.Header().Set("Content-Type", "application/json")
122- user, _ := shared.GetUserCtx(ctx)
123+ user, _ := shared.GetUser(ctx)
124 if !ensureUser(w, user) {
125 return
126 }
127@@ -574,7 +574,7 @@ func getProjectObjects(apiConfig *shared.ApiConfig, ctx ssh.Context) http.Handle
128 storage := apiConfig.Storage
129 return func(w http.ResponseWriter, r *http.Request) {
130 w.Header().Set("Content-Type", "application/json")
131- user, _ := shared.GetUserCtx(ctx)
132+ user, _ := shared.GetUser(ctx)
133 if !ensureUser(w, user) {
134 return
135 }
136@@ -616,7 +616,7 @@ func getAnalytics(apiConfig *shared.ApiConfig, ctx ssh.Context, sumtype, bytype,
137 dbpool := apiConfig.Dbpool
138 return func(w http.ResponseWriter, r *http.Request) {
139 w.Header().Set("Content-Type", "application/json")
140- user, _ := shared.GetUserCtx(ctx)
141+ user, _ := shared.GetUser(ctx)
142 if !ensureUser(w, user) {
143 return
144 }
145@@ -655,7 +655,7 @@ func getAnalytics(apiConfig *shared.ApiConfig, ctx ssh.Context, sumtype, bytype,
146
147 func CreateRoutes(apiConfig *shared.ApiConfig, ctx ssh.Context) []shared.Route {
148 logger := apiConfig.Cfg.Logger
149- pubkey, err := shared.GetPublicKeyCtx(ctx)
150+ pubkey, err := shared.GetPublicKey(ctx)
151 if err != nil {
152 logger.Error("could not get pubkey from ctx", "err", err.Error())
153 return []shared.Route{}