diff options
Diffstat (limited to 'forged/internal/incoming')
-rw-r--r-- | forged/internal/incoming/hooks/hooks.go | 5 | ||||
-rw-r--r-- | forged/internal/incoming/lmtp/lmtp.go | 5 | ||||
-rw-r--r-- | forged/internal/incoming/ssh/ssh.go | 11 | ||||
-rw-r--r-- | forged/internal/incoming/web/handler.go | 8 | ||||
-rw-r--r-- | forged/internal/incoming/web/handlers/group.go | 7 | ||||
-rw-r--r-- | forged/internal/incoming/web/handlers/index.go | 24 | ||||
-rw-r--r-- | forged/internal/incoming/web/handlers/not_implemented.go | 11 | ||||
-rw-r--r-- | forged/internal/incoming/web/handlers/repo/handler.go | 15 | ||||
-rw-r--r-- | forged/internal/incoming/web/handlers/repo/index.go | 8 | ||||
-rw-r--r-- | forged/internal/incoming/web/router.go | 59 | ||||
-rw-r--r-- | forged/internal/incoming/web/server.go | 8 | ||||
-rw-r--r-- | forged/internal/incoming/web/types/types.go | 10 |
12 files changed, 137 insertions, 34 deletions
diff --git a/forged/internal/incoming/hooks/hooks.go b/forged/internal/incoming/hooks/hooks.go index d0f57f5..941b03f 100644 --- a/forged/internal/incoming/hooks/hooks.go +++ b/forged/internal/incoming/hooks/hooks.go @@ -10,12 +10,14 @@ import ( "github.com/gliderlabs/ssh" "go.lindenii.runxiyu.org/forge/forged/internal/common/cmap" "go.lindenii.runxiyu.org/forge/forged/internal/common/misc" + "go.lindenii.runxiyu.org/forge/forged/internal/global" ) type Server struct { hookMap cmap.Map[string, hookInfo] socketPath string executablesPath string + globalData *global.GlobalData } type hookInfo struct { session ssh.Session @@ -30,11 +32,12 @@ type hookInfo struct { contribReq string } -func New(config Config) (server *Server) { +func New(config Config, globalData *global.GlobalData) (server *Server) { return &Server{ socketPath: config.Socket, executablesPath: config.Execs, hookMap: cmap.Map[string, hookInfo]{}, + globalData: globalData, } } diff --git a/forged/internal/incoming/lmtp/lmtp.go b/forged/internal/incoming/lmtp/lmtp.go index 61b1caf..d7e5ef4 100644 --- a/forged/internal/incoming/lmtp/lmtp.go +++ b/forged/internal/incoming/lmtp/lmtp.go @@ -8,6 +8,7 @@ import ( "time" "go.lindenii.runxiyu.org/forge/forged/internal/common/misc" + "go.lindenii.runxiyu.org/forge/forged/internal/global" ) type Server struct { @@ -16,15 +17,17 @@ type Server struct { maxSize int64 writeTimeout uint32 readTimeout uint32 + globalData *global.GlobalData } -func New(config Config) (server *Server) { +func New(config Config, globalData *global.GlobalData) (server *Server) { return &Server{ socket: config.Socket, domain: config.Domain, maxSize: config.MaxSize, writeTimeout: config.WriteTimeout, readTimeout: config.ReadTimeout, + globalData: globalData, } } diff --git a/forged/internal/incoming/ssh/ssh.go b/forged/internal/incoming/ssh/ssh.go index 9338eca..dc03501 100644 --- a/forged/internal/incoming/ssh/ssh.go +++ b/forged/internal/incoming/ssh/ssh.go @@ -9,26 +9,27 @@ import ( gliderssh "github.com/gliderlabs/ssh" "go.lindenii.runxiyu.org/forge/forged/internal/common/misc" + "go.lindenii.runxiyu.org/forge/forged/internal/global" gossh "golang.org/x/crypto/ssh" ) type Server struct { gliderServer *gliderssh.Server privkey gossh.Signer - pubkeyString string - pubkeyFP string net string addr string root string shutdownTimeout uint32 + globalData *global.GlobalData } -func New(config Config) (server *Server, err error) { +func New(config Config, globalData *global.GlobalData) (server *Server, err error) { server = &Server{ net: config.Net, addr: config.Addr, root: config.Root, shutdownTimeout: config.ShutdownTimeout, + globalData: globalData, } //exhaustruct:ignore var privkeyBytes []byte @@ -43,8 +44,8 @@ func New(config Config) (server *Server, err error) { return server, fmt.Errorf("parse SSH private key: %w", err) } - server.pubkeyString = misc.BytesToString(gossh.MarshalAuthorizedKey(server.privkey.PublicKey())) - server.pubkeyFP = gossh.FingerprintSHA256(server.privkey.PublicKey()) + server.globalData.SSHPubkey = misc.BytesToString(gossh.MarshalAuthorizedKey(server.privkey.PublicKey())) + server.globalData.SSHFingerprint = gossh.FingerprintSHA256(server.privkey.PublicKey()) server.gliderServer = &gliderssh.Server{ Handler: handle, diff --git a/forged/internal/incoming/web/handler.go b/forged/internal/incoming/web/handler.go index da2a2e0..bc50b33 100644 --- a/forged/internal/incoming/web/handler.go +++ b/forged/internal/incoming/web/handler.go @@ -5,6 +5,8 @@ import ( "net/http" "go.lindenii.runxiyu.org/forge/forged/internal/common/misc" + "go.lindenii.runxiyu.org/forge/forged/internal/database/queries" + "go.lindenii.runxiyu.org/forge/forged/internal/global" handlers "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/handlers" repoHandlers "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/handlers/repo" "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/templates" @@ -14,8 +16,8 @@ type handler struct { r *Router } -func NewHandler(cfg Config) http.Handler { - h := &handler{r: NewRouter().ReverseProxy(cfg.ReverseProxy)} +func NewHandler(cfg Config, globalData *global.GlobalData, queries *queries.Queries) *handler { + h := &handler{r: NewRouter().ReverseProxy(cfg.ReverseProxy).Global(globalData).Queries(queries)} staticFS := http.FileServer(http.Dir(cfg.StaticPath)) h.r.ANYHTTP("-/static/*rest", @@ -36,7 +38,7 @@ func NewHandler(cfg Config) http.Handler { indexHTTP := handlers.NewIndexHTTP(renderer) groupHTTP := handlers.NewGroupHTTP(renderer) repoHTTP := repoHandlers.NewHTTP(renderer) - notImpl := handlers.NewNotImplementedHTTP() + notImpl := handlers.NewNotImplementedHTTP(renderer) // Index h.r.GET("/", indexHTTP.Index) diff --git a/forged/internal/incoming/web/handlers/group.go b/forged/internal/incoming/web/handlers/group.go index 0c631c3..e56a3b5 100644 --- a/forged/internal/incoming/web/handlers/group.go +++ b/forged/internal/incoming/web/handlers/group.go @@ -12,7 +12,11 @@ type GroupHTTP struct { r templates.Renderer } -func NewGroupHTTP(r templates.Renderer) *GroupHTTP { return &GroupHTTP{r: r} } +func NewGroupHTTP(r templates.Renderer) *GroupHTTP { + return &GroupHTTP{ + r: r, + } +} func (h *GroupHTTP) Index(w http.ResponseWriter, r *http.Request, _ wtypes.Vars) { base := wtypes.Base(r) @@ -22,4 +26,3 @@ func (h *GroupHTTP) Index(w http.ResponseWriter, r *http.Request, _ wtypes.Vars) GroupPath: "/" + strings.Join(base.GroupPath, "/") + "/", }) } - diff --git a/forged/internal/incoming/web/handlers/index.go b/forged/internal/incoming/web/handlers/index.go index 259ca4a..22e6201 100644 --- a/forged/internal/incoming/web/handlers/index.go +++ b/forged/internal/incoming/web/handlers/index.go @@ -4,7 +4,9 @@ import ( "log" "net/http" + "go.lindenii.runxiyu.org/forge/forged/internal/database/queries" "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/templates" + "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/types" wtypes "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/types" ) @@ -12,13 +14,25 @@ type IndexHTTP struct { r templates.Renderer } -func NewIndexHTTP(r templates.Renderer) *IndexHTTP { return &IndexHTTP{r: r} } +func NewIndexHTTP(r templates.Renderer) *IndexHTTP { + return &IndexHTTP{ + r: r, + } +} -func (h *IndexHTTP) Index(w http.ResponseWriter, _ *http.Request, _ wtypes.Vars) { - err := h.r.Render(w, "index", struct { - Title string +func (h *IndexHTTP) Index(w http.ResponseWriter, r *http.Request, _ wtypes.Vars) { + groups, err := types.Base(r).Queries.GetRootGroups(r.Context()) + if err != nil { + http.Error(w, "failed to get root groups", http.StatusInternalServerError) + log.Println("failed to get root groups", "error", err) + return + } + err = h.r.Render(w, "index", struct { + BaseData *types.BaseData + Groups []queries.GetRootGroupsRow }{ - Title: "Home", + BaseData: types.Base(r), + Groups: groups, }) if err != nil { log.Println("failed to render index page", "error", err) diff --git a/forged/internal/incoming/web/handlers/not_implemented.go b/forged/internal/incoming/web/handlers/not_implemented.go index 472f73b..6813c88 100644 --- a/forged/internal/incoming/web/handlers/not_implemented.go +++ b/forged/internal/incoming/web/handlers/not_implemented.go @@ -3,12 +3,19 @@ package handlers import ( "net/http" + "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/templates" wtypes "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/types" ) -type NotImplementedHTTP struct{} +type NotImplementedHTTP struct { + r templates.Renderer +} -func NewNotImplementedHTTP() *NotImplementedHTTP { return &NotImplementedHTTP{} } +func NewNotImplementedHTTP(r templates.Renderer) *NotImplementedHTTP { + return &NotImplementedHTTP{ + r: r, + } +} func (h *NotImplementedHTTP) Handle(w http.ResponseWriter, _ *http.Request, _ wtypes.Vars) { http.Error(w, "not implemented", http.StatusNotImplemented) diff --git a/forged/internal/incoming/web/handlers/repo/handler.go b/forged/internal/incoming/web/handlers/repo/handler.go new file mode 100644 index 0000000..2881d7d --- /dev/null +++ b/forged/internal/incoming/web/handlers/repo/handler.go @@ -0,0 +1,15 @@ +package repo + +import ( + "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/templates" +) + +type HTTP struct { + r templates.Renderer +} + +func NewHTTP(r templates.Renderer) *HTTP { + return &HTTP{ + r: r, + } +} diff --git a/forged/internal/incoming/web/handlers/repo/index.go b/forged/internal/incoming/web/handlers/repo/index.go index dd1382f..1a804b2 100644 --- a/forged/internal/incoming/web/handlers/repo/index.go +++ b/forged/internal/incoming/web/handlers/repo/index.go @@ -4,16 +4,9 @@ import ( "net/http" "strings" - "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/templates" wtypes "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/types" ) -type HTTP struct { - r templates.Renderer -} - -func NewHTTP(r templates.Renderer) *HTTP { return &HTTP{r: r} } - func (h *HTTP) Index(w http.ResponseWriter, r *http.Request, v wtypes.Vars) { base := wtypes.Base(r) repo := v["repo"] @@ -25,4 +18,3 @@ func (h *HTTP) Index(w http.ResponseWriter, r *http.Request, v wtypes.Vars) { Repo: repo, }) } - diff --git a/forged/internal/incoming/web/router.go b/forged/internal/incoming/web/router.go index 46eb935..7c2717d 100644 --- a/forged/internal/incoming/web/router.go +++ b/forged/internal/incoming/web/router.go @@ -1,15 +1,18 @@ package web import ( + "fmt" "net/http" "net/url" "sort" "strings" + "go.lindenii.runxiyu.org/forge/forged/internal/database/queries" + "go.lindenii.runxiyu.org/forge/forged/internal/global" wtypes "go.lindenii.runxiyu.org/forge/forged/internal/incoming/web/types" ) -type UserResolver func(*http.Request) (id int, username string, err error) +type UserResolver func(*http.Request) (id string, username string, err error) type ErrorRenderers struct { BadRequest func(http.ResponseWriter, *wtypes.BaseData, string) @@ -57,13 +60,21 @@ type Router struct { routes []route errors ErrorRenderers user UserResolver - global any + global *global.GlobalData reverseProxy bool + queries *queries.Queries } func NewRouter() *Router { return &Router{} } -func (r *Router) Global(v any) *Router { r.global = v; return r } +func (r *Router) Global(g *global.GlobalData) *Router { + r.global = g + return r +} +func (r *Router) Queries(q *queries.Queries) *Router { + r.queries = q + return r +} func (r *Router) ReverseProxy(enabled bool) *Router { r.reverseProxy = enabled; return r } func (r *Router) Errors(e ErrorRenderers) *Router { r.errors = e; return r } func (r *Router) UserResolver(u UserResolver) *Router { r.user = u; return r } @@ -138,6 +149,13 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { Global: r.global, URLSegments: segments, DirMode: dirMode, + Queries: r.queries, + } + + bd.RefType, bd.RefName, err = GetParamRefTypeName(req) + if err != nil { + r.err400(w, bd, "Error parsing ref query parameters: "+err.Error()) + return } if r.user != nil { @@ -379,3 +397,38 @@ func (r *Router) err500(w http.ResponseWriter, b *wtypes.BaseData, msg string) { } http.Error(w, msg, http.StatusInternalServerError) } + +func GetParamRefTypeName(request *http.Request) (retRefType, retRefName string, err error) { + rawQuery := request.URL.RawQuery + queryValues, err := url.ParseQuery(rawQuery) + if err != nil { + return + } + done := false + for _, refType := range []string{"commit", "branch", "tag"} { + refName, ok := queryValues[refType] + if ok { + if done { + err = errDupRefSpec + return + } + done = true + if len(refName) != 1 { + err = errDupRefSpec + return + } + retRefName = refName[0] + retRefType = refType + } + } + if !done { + retRefType = "" + retRefName = "" + err = nil // actually returning empty strings is enough? + } + return +} + +var ( + errDupRefSpec = fmt.Errorf("duplicate ref specifications") +) diff --git a/forged/internal/incoming/web/server.go b/forged/internal/incoming/web/server.go index 6229bf0..f81886f 100644 --- a/forged/internal/incoming/web/server.go +++ b/forged/internal/incoming/web/server.go @@ -9,6 +9,8 @@ import ( "time" "go.lindenii.runxiyu.org/forge/forged/internal/common/misc" + "go.lindenii.runxiyu.org/forge/forged/internal/database/queries" + "go.lindenii.runxiyu.org/forge/forged/internal/global" ) type Server struct { @@ -17,11 +19,12 @@ type Server struct { root string httpServer *http.Server shutdownTimeout uint32 + globalData *global.GlobalData } -func New(config Config) (server *Server) { +func New(config Config, globalData *global.GlobalData, queries *queries.Queries) *Server { httpServer := &http.Server{ - Handler: NewHandler(config), + Handler: NewHandler(config, globalData, queries), ReadTimeout: time.Duration(config.ReadTimeout) * time.Second, WriteTimeout: time.Duration(config.WriteTimeout) * time.Second, IdleTimeout: time.Duration(config.IdleTimeout) * time.Second, @@ -33,6 +36,7 @@ func New(config Config) (server *Server) { root: config.Root, shutdownTimeout: config.ShutdownTimeout, httpServer: httpServer, + globalData: globalData, } } diff --git a/forged/internal/incoming/web/types/types.go b/forged/internal/incoming/web/types/types.go index d47b13a..1301fe9 100644 --- a/forged/internal/incoming/web/types/types.go +++ b/forged/internal/incoming/web/types/types.go @@ -3,18 +3,24 @@ package types import ( "context" "net/http" + + "go.lindenii.runxiyu.org/forge/forged/internal/database/queries" + "go.lindenii.runxiyu.org/forge/forged/internal/global" ) // BaseData is per-request context computed by the router and read by handlers. // Keep it small and stable; page-specific data should live in view models. type BaseData struct { - Global any - UserID int + UserID string Username string URLSegments []string DirMode bool GroupPath []string SeparatorIndex int + RefType string + RefName string + Global *global.GlobalData + Queries *queries.Queries } type ctxKey struct{} |