~netlandish/links

19a92f84dd29250347bca9286449093ba585de01 — Peter Sanchez 9 months ago 65419e6
Working with custom user domain link listing. Still more to do
4 files changed, 45 insertions(+), 26 deletions(-)

M cmd/links/main.go
M core/routes.go
M domain/logic.go
M domain/middleware.go
M cmd/links/main.go => cmd/links/main.go +0 -16
@@ 17,7 17,6 @@ import (
	"links/cmd"
	"links/core"
	"links/domain"
	"links/internal/localizer"
	"links/list"
	"links/mattermost"
	"links/models"


@@ 29,7 28,6 @@ import (

	work "git.sr.ht/~sircmpwn/dowork"
	"github.com/labstack/echo/v4"
	"netlandish.com/x/gobwebs"
	formguard "netlandish.com/x/gobwebs-formguard"
	oauth2 "netlandish.com/x/gobwebs-oauth2"
	feedback "netlandish.com/x/gobwebs-ses-feedback"


@@ 276,20 274,6 @@ func run() error {
	oauthGroup := e.Group("/oauth2")
	oauthSvc := oauth2.NewService(oauthGroup, "oauth2", &oauthConfig)
	e.GET("/.well-known/oauth-authorization-server", oauthSvc.OAuthMetadata).Name = "oauth2:auth_server"
	e.GET("/", func(c echo.Context) error {
		gctx := c.(*server.Context)
		lt := localizer.GetSessionLocalizer(c)
		pd := localizer.NewPageData(lt.Translate("Welcome to Link Taco"))
		pd.Data["intro"] = lt.Translate("lorem ipsum")
		pd.Data["login"] = lt.Translate("Login")
		pd.Data["email_address"] = lt.Translate("Email Address")
		pd.Data["password"] = lt.Translate("Password")
		pd.Data["forgot_password"] = lt.Translate("Forgot Password?")
		pd.Data["login"] = lt.Translate("Login")
		pd.Data["no_accounts"] = lt.Translate("No accounts? Click here to create one")
		gMap := gobwebs.Map{"pd": pd}
		return gctx.Render(http.StatusOK, "index.html", gMap)
	}).Name = "index"

	if len(os.Args) > 1 {
		switch os.Args[1] {

M core/routes.go => core/routes.go +25 -0
@@ 6,6 6,7 @@ import (
	"fmt"
	"links"
	"links/analytics"
	"links/domain"
	"links/internal/localizer"
	"links/models"
	"net/http"


@@ 34,6 35,7 @@ type Service struct {

// RegisterRoutes ...
func (s *Service) RegisterRoutes() {
	s.eg.GET("/", s.Homepage).Name = "index"
	s.eg.GET("/:slug", s.OrgLinksList).Name = s.RouteName("org_link_list")
	s.eg.GET("/recent", s.OrgLinksList).Name = s.RouteName("recent_link_list")
	s.eg.GET("/popular", s.PopularLinkList).Name = s.RouteName("popular_link_list")


@@ 87,6 89,29 @@ func (s *Service) RegisterRoutes() {
	s.eg.GET("/tag-autocomplete", s.TagAutocomplete).Name = s.RouteName("tag_autocomplete")
}

func (s *Service) Homepage(c echo.Context) error {
	// If user custom domain, don't parse homepage. Just show the assigned
	// org public list
	domain := domain.ForContext(c.Request().Context())
	if domain.Level == models.DomainLevelUser && domain.OrgID.Valid {
		return s.OrgLinksList(c)
	}

	gctx := c.(*server.Context)
	lt := localizer.GetSessionLocalizer(c)
	pd := localizer.NewPageData(lt.Translate("Welcome to Link Taco"))
	pd.Data["intro"] = lt.Translate("lorem ipsum")
	pd.Data["login"] = lt.Translate("Login")
	pd.Data["email_address"] = lt.Translate("Email Address")
	pd.Data["password"] = lt.Translate("Password")
	pd.Data["forgot_password"] = lt.Translate("Forgot Password?")
	pd.Data["login"] = lt.Translate("Login")
	pd.Data["no_accounts"] = lt.Translate("No accounts? Click here to create one")
	gMap := gobwebs.Map{"pd": pd}
	return gctx.Render(http.StatusOK, "index.html", gMap)

}

func (s *Service) FeatureTour(c echo.Context) error {
	gctx := c.(*server.Context)
	lt := localizer.GetSessionLocalizer(c)

M domain/logic.go => domain/logic.go +6 -3
@@ 17,11 17,14 @@ import (

var ipMap map[string]net.IP

func ValidDomain(ctx context.Context, host string, service int, active bool) ([]*models.Domain, error) {
func ValidDomain(
	ctx context.Context, host string, service int, active bool) ([]*models.Domain, error) {
	// Remove :PORT from host name
	host = strings.SplitN(host, ":", 2)[0]
	h, err := idna.Lookup.ToASCII(host)
	if err != nil {
		// To account for IP:Port situations we allow the host unaltered.
		h = host
		// XXX Add proper logging here
		return nil, err
	}
	opts := &database.FilterOptions{
		Filter: sq.And{

M domain/middleware.go => domain/middleware.go +14 -7
@@ 77,13 77,17 @@ func DomainContext(service int) echo.MiddlewareFunc {

// LinksUserDomain will bind a user domain to the domain organization's public links.
// It uses internal URL path mangling to produce the magic handler routing.
// Not in use. Unfortunately this magic was too convoluted to get working due to other
// design decisions made in this project and also in gobwebs
func LinksUserDomain(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		req := c.Request()
		domain := ForContext(req.Context())
		if domain.Level == models.DomainLevelUser && domain.OrgID.Valid {
			gctx := c.(*server.Context)
			// Active user domain
			if req.URL.Path != "/" && req.URL.Path != "" {
			if req.URL.Path != "/" && req.URL.Path != "" &&
				!strings.HasPrefix(req.URL.Path, gctx.Server.Config.StaticURL+"/") {
				// We don't allow other paths on non system domains
				url, err := req.URL.Parse("/")
				if err != nil {


@@ 91,12 95,15 @@ func LinksUserDomain(next echo.HandlerFunc) echo.HandlerFunc {
				}
				return c.Redirect(http.StatusMovedPermanently, url.String())
			}
			url, err := req.URL.Parse("/" + domain.OrgSlug.String)
			if err != nil {
				return err
			}
			req.URL = url
			c.SetRequest(req)
			// This is the magic that should be removed. I'm leaving it for
			// reference at this point. Will think if it makes sense to bring
			// this back.
			//url, err := req.URL.Parse("/" + domain.OrgSlug.String)
			//if err != nil {
			//    return err
			//}
			//req.URL = url
			//c.SetRequest(req)
		}
		return next(c)
	}