M cmd/gohome/main.go => cmd/gohome/main.go +1 -6
@@ 15,7 15,6 @@ import (
"github.com/alexedwards/scs/v2"
"github.com/labstack/echo/v4"
"netlandish.com/x/gobwebs/config"
- "netlandish.com/x/gobwebs/crypto"
"netlandish.com/x/gobwebs/database"
"netlandish.com/x/gobwebs/server"
"petersanchez.com/x/migrate"
@@ 37,10 36,6 @@ func run() error {
return err
}
- entropy, ok := config.File.Get("access", "entropy")
- if !ok {
- return fmt.Errorf("No access entropy set. Required value")
- }
root, _ := config.File.Get("gohome", "root")
if root != "" && !strings.HasPrefix(root, "/") {
root = fmt.Sprintf("/%s", root)
@@ 77,7 72,7 @@ func run() error {
DefaultMiddlewareWithConfig(mwConf).
WithMiddleware(
database.Middleware(db),
- crypto.Middleware(entropy),
+ gohome.Middleware(root),
)
svc := e.Group(root)
M config.example.ini => config.example.ini +0 -3
@@ 52,9 52,6 @@ connection-string = gohome.db
# Defaults to: ./
root-directory=./
-[access]
-entropy=Entropy value
-
[gohome]
# Set to the value of the root URL path. Ie, if the repo URL is
# yourdomain.com/x/repo-name then the root value is 'x'. leave blank
M middleware.go => middleware.go +54 -0
@@ 1,11 1,65 @@
package gohome
import (
+ "context"
+ "fmt"
"net/http"
+ "strings"
"github.com/labstack/echo/v4"
)
+var rootCtxKey = &contextKey{"root"}
+
+type contextKey struct {
+ name string
+}
+
+// Context adds user object to context for immediate use
+func Context(ctx context.Context, root string) context.Context {
+ return context.WithValue(ctx, rootCtxKey, root)
+}
+
+// ForContext pulls user value for context
+func ForContext(ctx context.Context) string {
+ root, ok := ctx.Value(rootCtxKey).(string)
+ if !ok {
+ return ""
+ }
+ return root
+}
+
+// Middleware adds root path to the context
+func Middleware(root string) echo.MiddlewareFunc {
+ return func(next echo.HandlerFunc) echo.HandlerFunc {
+ return func(c echo.Context) error {
+ c.SetRequest(c.Request().WithContext(Context(c.Request().Context(), root)))
+ return next(c)
+ }
+ }
+}
+
+// RepoMiddleware will check the request path and see if it matches a repo.
+func RepoMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
+ return func(c echo.Context) error {
+ path := c.Request().URL.Path
+ if !strings.HasPrefix(path, "/") {
+ path = fmt.Sprintf("/%s", path)
+ }
+ adminPath := c.Echo().Reverse("home:admin_home")
+ if strings.HasPrefix(path, adminPath) {
+ // Using the --admin-- url routes. Don't bother doing any
+ // further checks.
+ return next(c)
+ }
+
+ root := ForContext(c.Request().Context())
+ path = strings.TrimPrefix(path, root)
+ path = strings.TrimPrefix(path, "/")
+ return GetRepoFromPath(c, path)
+ }
+}
+
// AuthRequired will ensure that the user has entered the correct password
func AuthRequired(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
M routes.go => routes.go +58 -0
@@ 3,11 3,15 @@ package gohome
import (
"fmt"
"net/http"
+ "net/url"
"strconv"
+ "strings"
+ sq "github.com/Masterminds/squirrel"
"github.com/alexedwards/argon2id"
"github.com/labstack/echo/v4"
"netlandish.com/x/gobwebs"
+ "netlandish.com/x/gobwebs/database"
"netlandish.com/x/gobwebs/messages"
"netlandish.com/x/gobwebs/server"
"netlandish.com/x/gobwebs/validate"
@@ 218,6 222,60 @@ func (s *Service) RepoAddEdit(c echo.Context) error {
return gctx.Render(http.StatusOK, "add_edit.html", gmap)
}
+// GetRepo will check the path for an active repo and return it
+func GetRepoFromPath(c echo.Context, path string) error {
+ parts := strings.Split(path, "/")
+ if len(parts) > 3 {
+ // TODO re-think this?
+ parts = parts[:3]
+ }
+
+ var (
+ repo *Repo
+ rname string
+ )
+ for i := 0; i < 3; i++ {
+ // XXX Is this even needed? Should it just be the first value (parts[0])?
+ rname = strings.Join(parts[:i+1], "/")
+ opts := &database.FilterOptions{
+ Filter: sq.And{
+ sq.Eq{"reponame": strings.ToLower(rname)},
+ sq.Eq{"is_active": true},
+ },
+ Limit: 1,
+ }
+ repos, err := GetRepos(c.Request().Context(), opts)
+ if err != nil {
+ return err
+ }
+ if len(repos) == 0 {
+ continue
+ }
+ repo = repos[0]
+ break
+ }
+
+ if repo == nil {
+ return echo.NotFoundHandler(c)
+ }
+
+ gctx := c.(*server.Context)
+ if c.QueryParams().Get("go-get") == "1" {
+ root := ForContext(c.Request().Context())
+ fpath, err := url.JoinPath(root, rname)
+ if err != nil {
+ return err
+ }
+ rdomain := fmt.Sprintf("%s%s", gctx.Server.Config.Domain, fpath)
+ return c.HTML(http.StatusOK,
+ fmt.Sprintf(`<meta name="go-import" content="%s %s %s" />`,
+ rdomain, repo.RepoType, repo.RepoURL),
+ )
+ }
+ gmap := gobwebs.Map{"repo": repo}
+ return gctx.Render(http.StatusOK, "repo_detail.html", gmap)
+}
+
// RouteName ...
func (s *Service) RouteName(value string) string {
return fmt.Sprintf("%s:%s", s.name, value)